@ljwei-stak/dsh-model-route-bot 0.66.4 → 0.67.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.
Files changed (271) hide show
  1. package/.dsh-plugin/bot-product.mjs +81 -5
  2. package/.dsh-plugin/client.js +17490 -1791
  3. package/README.i18n.yaml +4 -4
  4. package/README.md +409 -364
  5. package/README.zh.md +409 -364
  6. package/apps/integration-client/README.md +31 -7
  7. package/apps/integration-client/api.mjs +14 -3
  8. package/apps/integration-client/binding-editor.jsx +308 -109
  9. package/apps/integration-client/binding-model.mjs +262 -0
  10. package/apps/integration-client/binding.css +144 -0
  11. package/apps/integration-client/bot-model-status.mjs +18 -0
  12. package/apps/integration-client/bot-profile-identity.jsx +197 -0
  13. package/apps/integration-client/bot-profile.css +57 -0
  14. package/apps/integration-client/bot-profile.mjs +97 -0
  15. package/apps/integration-client/bot-settings-dialog.css +18 -0
  16. package/apps/integration-client/bot-settings-dialog.jsx +111 -0
  17. package/apps/integration-client/bot-thread-header-bridge.css +20 -0
  18. package/apps/integration-client/bot-thread-header.jsx +278 -0
  19. package/apps/integration-client/bot-threads-panel.jsx +378 -0
  20. package/apps/integration-client/bot-threads.css +169 -0
  21. package/apps/integration-client/chat-design.mjs +250 -0
  22. package/apps/integration-client/chat-ui.jsx +175 -0
  23. package/apps/integration-client/chat.css +477 -0
  24. package/apps/integration-client/composer-draft-binding.mjs +50 -0
  25. package/apps/integration-client/composer-draft-bound.jsx +14 -0
  26. package/apps/integration-client/composer-draft-host.jsx +142 -0
  27. package/apps/integration-client/composer-draft-session.jsx +287 -0
  28. package/apps/integration-client/composer-draft-witness.mjs +115 -0
  29. package/apps/integration-client/composer-draft.css +4 -0
  30. package/apps/integration-client/composer-draft.mjs +322 -0
  31. package/apps/integration-client/contact-attention.jsx +54 -0
  32. package/apps/integration-client/data-panel.jsx +439 -0
  33. package/apps/integration-client/data.css +69 -0
  34. package/apps/integration-client/desktop-bridge.mjs +1 -0
  35. package/apps/integration-client/desktop-http-socket.mjs +49 -0
  36. package/apps/integration-client/desktop-keyboard.mjs +32 -0
  37. package/apps/integration-client/desktop-pane.jsx +99 -30
  38. package/apps/integration-client/desktop-stream.mjs +13 -3
  39. package/apps/integration-client/desktop-tools.jsx +19 -0
  40. package/apps/integration-client/desktop-touch.mjs +27 -0
  41. package/apps/integration-client/desktop.css +41 -0
  42. package/apps/integration-client/independent-chat-controller.mjs +224 -0
  43. package/apps/integration-client/independent-chat-entry.jsx +61 -0
  44. package/apps/integration-client/independent-chat-navigation.mjs +21 -0
  45. package/apps/integration-client/independent-chat-page.jsx +148 -0
  46. package/apps/integration-client/independent-chat-rich.jsx +64 -0
  47. package/apps/integration-client/independent-chat-rich.mjs +30 -0
  48. package/apps/integration-client/independent-chat.css +73 -0
  49. package/apps/integration-client/index.jsx +24 -16
  50. package/apps/integration-client/library-panel.jsx +4 -1
  51. package/apps/integration-client/licenses/jsqr-1.4.0-LICENSE.txt +202 -0
  52. package/apps/integration-client/main-route-editor.jsx +94 -0
  53. package/apps/integration-client/main-route-model.mjs +100 -0
  54. package/apps/integration-client/model-picker.css +37 -0
  55. package/apps/integration-client/model-picker.jsx +83 -0
  56. package/apps/integration-client/native-activity.css +141 -0
  57. package/apps/integration-client/native-activity.jsx +276 -0
  58. package/apps/integration-client/native-activity.mjs +384 -0
  59. package/apps/integration-client/notifications-panel.jsx +186 -0
  60. package/apps/integration-client/notifications.css +126 -0
  61. package/apps/integration-client/pairing-qr.jsx +79 -0
  62. package/apps/integration-client/panels.jsx +126 -115
  63. package/apps/integration-client/product-slots.jsx +46 -0
  64. package/apps/integration-client/routine-recorder.mjs +23 -2
  65. package/apps/integration-client/secure-pairing.jsx +84 -0
  66. package/apps/integration-client/tasks-panel.jsx +32 -10
  67. package/apps/integration-client/ui-icons.jsx +17 -0
  68. package/apps/integration-client/usage-explorer.jsx +43 -0
  69. package/apps/integration-client/usage-report.mjs +71 -0
  70. package/apps/integration-client/usage.css +34 -0
  71. package/apps/integration-client/web-panel-model.mjs +140 -0
  72. package/apps/integration-client/web-panel-page.jsx +221 -0
  73. package/apps/integration-client/web-panel-pins-live.jsx +28 -0
  74. package/apps/integration-client/web-panel.css +139 -0
  75. package/apps/integration-client/workspace-model.mjs +67 -0
  76. package/apps/integration-client/workspace-navigation.mjs +56 -0
  77. package/apps/integration-client/workspace-ui.jsx +173 -0
  78. package/apps/integration-client/workspace.css +332 -0
  79. package/modules/bot-runtime/SOURCE.json +176 -50
  80. package/modules/bot-runtime/index.mjs +169 -13
  81. package/modules/bot-runtime/product-overlay/OVERLAY.json +128 -2
  82. package/modules/bot-runtime/product-overlay/base/src/client/header.js +244 -0
  83. package/modules/bot-runtime/product-overlay/base/src/client/learning-card.js +202 -0
  84. package/modules/bot-runtime/product-overlay/base/src/client/model-menu.js +371 -0
  85. package/modules/bot-runtime/product-overlay/base/src/client/secret-card.js +363 -0
  86. package/modules/bot-runtime/product-overlay/base/src/client/sources.js +68 -0
  87. package/modules/bot-runtime/product-overlay/base/src/client/turn-error.js +260 -0
  88. package/modules/bot-runtime/product-overlay/base/src/host/channel.js +647 -0
  89. package/modules/bot-runtime/product-overlay/base/src/host/memory.js +2050 -0
  90. package/modules/bot-runtime/product-overlay/base/src/host/models.js +314 -0
  91. package/modules/bot-runtime/product-overlay/base/src/host/parts.js +1473 -0
  92. package/modules/bot-runtime/product-overlay/base/src/host/privacy.js +368 -0
  93. package/modules/bot-runtime/product-overlay/base/src/host/roster.js +776 -0
  94. package/modules/bot-runtime/product-overlay/base/src/host/store.js +512 -0
  95. package/modules/bot-runtime/product-overlay/base/src/host/usage.js +653 -0
  96. package/modules/bot-runtime/product-overlay/patches/src/client/details-drawer.js.patch +48 -2
  97. package/modules/bot-runtime/product-overlay/patches/src/client/header.js.patch +41 -0
  98. package/modules/bot-runtime/product-overlay/patches/src/client/index.js.patch +33 -1
  99. package/modules/bot-runtime/product-overlay/patches/src/client/learning-card.js.patch +20 -0
  100. package/modules/bot-runtime/product-overlay/patches/src/client/model-menu.js.patch +24 -0
  101. package/modules/bot-runtime/product-overlay/patches/src/client/secret-card.js.patch +25 -0
  102. package/modules/bot-runtime/product-overlay/patches/src/client/sources.js.patch +52 -0
  103. package/modules/bot-runtime/product-overlay/patches/src/client/turn-error.js.patch +23 -0
  104. package/modules/bot-runtime/product-overlay/patches/src/host/channel.js.patch +46 -0
  105. package/modules/bot-runtime/product-overlay/patches/src/host/memory.js.patch +11 -0
  106. package/modules/bot-runtime/product-overlay/patches/src/host/models.js.patch +16 -0
  107. package/modules/bot-runtime/product-overlay/patches/src/host/parts.js.patch +95 -0
  108. package/modules/bot-runtime/product-overlay/patches/src/host/privacy.js.patch +11 -0
  109. package/modules/bot-runtime/product-overlay/patches/src/host/roster.js.patch +145 -0
  110. package/modules/bot-runtime/product-overlay/patches/src/host/store.js.patch +68 -0
  111. package/modules/bot-runtime/product-overlay/patches/src/host/usage.js.patch +11 -0
  112. package/modules/bot-runtime/read-model.mjs +19 -4
  113. package/modules/bot-runtime/vendor/ds-bot/src/client/details-drawer.js +15 -5
  114. package/modules/bot-runtime/vendor/ds-bot/src/client/header.js +9 -2
  115. package/modules/bot-runtime/vendor/ds-bot/src/client/index.js +9 -2
  116. package/modules/bot-runtime/vendor/ds-bot/src/client/learning-card.js +2 -2
  117. package/modules/bot-runtime/vendor/ds-bot/src/client/model-menu.js +5 -3
  118. package/modules/bot-runtime/vendor/ds-bot/src/client/secret-card.js +3 -3
  119. package/modules/bot-runtime/vendor/ds-bot/src/client/sources.js +25 -2
  120. package/modules/bot-runtime/vendor/ds-bot/src/client/turn-error.js +3 -2
  121. package/modules/bot-runtime/vendor/ds-bot/src/host/channel.js +14 -2
  122. package/modules/bot-runtime/vendor/ds-bot/src/host/memory.js +1 -1
  123. package/modules/bot-runtime/vendor/ds-bot/src/host/models.js +7 -0
  124. package/modules/bot-runtime/vendor/ds-bot/src/host/parts.js +26 -9
  125. package/modules/bot-runtime/vendor/ds-bot/src/host/privacy.js +1 -1
  126. package/modules/bot-runtime/vendor/ds-bot/src/host/roster.js +112 -3
  127. package/modules/bot-runtime/vendor/ds-bot/src/host/store.js +34 -1
  128. package/modules/bot-runtime/vendor/ds-bot/src/host/usage.js +1 -1
  129. package/modules/independent-runtime/index.mjs +152 -62
  130. package/modules/independent-runtime/remote-tools.mjs +8 -5
  131. package/modules/openmaus-protocol/NOTICE +10 -0
  132. package/modules/openmaus-protocol/README.md +15 -0
  133. package/modules/openmaus-protocol/SOURCE.json +68 -0
  134. package/modules/openmaus-protocol/dist/protocol.mjs +1203 -0
  135. package/modules/openmaus-protocol/index.mjs +1 -0
  136. package/modules/openmaus-protocol/transport.mjs +77 -0
  137. package/modules/openmaus-protocol/vendor/LICENSE +202 -0
  138. package/modules/openmaus-protocol/vendor/companion/src/e2e/README.md +405 -0
  139. package/modules/openmaus-protocol/vendor/companion/src/e2e/credentials.ts +128 -0
  140. package/modules/openmaus-protocol/vendor/companion/src/e2e/descriptor.ts +84 -0
  141. package/modules/openmaus-protocol/vendor/companion/src/e2e/noise.ts +456 -0
  142. package/modules/openmaus-protocol/vendor/companion/src/e2e/phone.ts +104 -0
  143. package/modules/openmaus-protocol/vendor/companion/src/e2e/session.ts +417 -0
  144. package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.json +2565 -0
  145. package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.sha256 +1 -0
  146. package/modules/openmaus-protocol/vendor/companion/src/e2e/yamux.ts +335 -0
  147. package/package.json +18 -6
  148. package/packages/bot-acp/README.md +156 -0
  149. package/packages/bot-acp/licenses/LICENSE-OpenMausBot +202 -0
  150. package/packages/bot-acp/licenses/NOTICE.md +27 -0
  151. package/packages/bot-acp/src/acp-adapter.mjs +795 -0
  152. package/packages/bot-acp/src/acp-host.mjs +148 -0
  153. package/packages/bot-acp/src/native-launch.mjs +121 -0
  154. package/packages/bot-acp/src/permission-policy.mjs +283 -0
  155. package/packages/bot-acp/src/rpc-codec.mjs +265 -0
  156. package/packages/bot-acp/src/session-core.mjs +581 -0
  157. package/packages/bot-acp/src/stdio-rpc.mjs +329 -0
  158. package/packages/bot-engines/README.md +281 -0
  159. package/packages/bot-engines/licenses/LICENSE-OpenMausBot +202 -0
  160. package/packages/bot-engines/licenses/NOTICE.md +32 -0
  161. package/packages/bot-engines/src/claude-engine.mjs +772 -0
  162. package/packages/bot-engines/src/claude-llm-adapter.mjs +797 -0
  163. package/packages/bot-engines/src/claude-llm-turn.mjs +292 -0
  164. package/packages/bot-engines/src/claude-permission-broker.mjs +130 -0
  165. package/packages/bot-engines/src/claude-permission-proxy.mjs +87 -0
  166. package/packages/bot-engines/src/claude-protocol.mjs +177 -0
  167. package/packages/bot-engines/src/driver-catalog.mjs +334 -0
  168. package/packages/bot-engines/src/host-loop-request.mjs +95 -0
  169. package/packages/bot-engines/src/host-registrations.mjs +105 -0
  170. package/packages/capability-broker/src/cli-bootstrap.mjs +86 -16
  171. package/packages/capability-broker/src/cli-bridge-response.mjs +80 -0
  172. package/packages/capability-broker/src/cli-stdio-bridge.mjs +21 -8
  173. package/packages/cli-runtime/src/codex-session-core.mjs +4 -0
  174. package/packages/cli-runtime/src/native-cli-output.mjs +57 -0
  175. package/packages/cli-runtime/src/native-peer.ps1 +51 -3
  176. package/packages/cli-runtime/src/native-process.mjs +77 -14
  177. package/packages/model-router-plugin/package.json +1 -1
  178. package/packages/orchestration/src/binding-product.mjs +19 -0
  179. package/packages/orchestration/src/bot-data-actions.mjs +45 -0
  180. package/packages/orchestration/src/bot-data-chart.mjs +109 -0
  181. package/packages/orchestration/src/bot-data-context.mjs +44 -0
  182. package/packages/orchestration/src/bot-data-engine.mjs +809 -0
  183. package/packages/orchestration/src/bot-data-io.mjs +186 -0
  184. package/packages/orchestration/src/bot-data-sql.mjs +195 -0
  185. package/packages/orchestration/src/bot-data-surface.mjs +144 -0
  186. package/packages/orchestration/src/bot-data-tools.mjs +68 -0
  187. package/packages/orchestration/src/bot-data-worker.mjs +228 -0
  188. package/packages/orchestration/src/bot-independent-execution.mjs +195 -0
  189. package/packages/orchestration/src/bot-independent-stream.mjs +74 -0
  190. package/packages/orchestration/src/bot-loop.mjs +152 -19
  191. package/packages/orchestration/src/bot-notifications.mjs +159 -0
  192. package/packages/orchestration/src/bot-policy.mjs +43 -4
  193. package/packages/orchestration/src/bot-profile.mjs +171 -0
  194. package/packages/orchestration/src/bot-routine.mjs +4 -4
  195. package/packages/orchestration/src/bot-runtime-assembly.mjs +255 -8
  196. package/packages/orchestration/src/bot-runtime-switch.mjs +13 -2
  197. package/packages/orchestration/src/bot-serving.mjs +164 -0
  198. package/packages/orchestration/src/bot-session-store.mjs +105 -9
  199. package/packages/orchestration/src/bot-settings.mjs +50 -11
  200. package/packages/orchestration/src/bot-thread-admission.mjs +84 -0
  201. package/packages/orchestration/src/bot-thread-host.mjs +187 -0
  202. package/packages/orchestration/src/bot-threads.mjs +790 -0
  203. package/packages/orchestration/src/data-product-access.mjs +37 -0
  204. package/packages/orchestration/src/data-tool-contract.mjs +291 -0
  205. package/packages/orchestration/src/desktop-http-carrier.mjs +120 -0
  206. package/packages/orchestration/src/desktop-proxy.mjs +311 -0
  207. package/packages/orchestration/src/desktop-sessions.mjs +43 -9
  208. package/packages/orchestration/src/ds-lifecycle.mjs +31 -4
  209. package/packages/orchestration/src/grant-refresh-queue.mjs +17 -0
  210. package/packages/orchestration/src/independent-chat-page.mjs +39 -0
  211. package/packages/orchestration/src/independent-chat-service.mjs +308 -0
  212. package/packages/orchestration/src/independent-context-state.mjs +44 -0
  213. package/packages/orchestration/src/independent-message-wire.mjs +84 -0
  214. package/packages/orchestration/src/independent-tool-catalog.mjs +175 -0
  215. package/packages/orchestration/src/independent-tool-families.mjs +73 -0
  216. package/packages/orchestration/src/independent-tool-host.mjs +344 -0
  217. package/packages/orchestration/src/main-bot-grant.mjs +15 -0
  218. package/packages/orchestration/src/main-model-routes.mjs +208 -0
  219. package/packages/orchestration/src/model-accounting.mjs +99 -35
  220. package/packages/orchestration/src/model-auxiliary-dispatch.mjs +187 -0
  221. package/packages/orchestration/src/model-loop-frame.mjs +179 -0
  222. package/packages/orchestration/src/model-prepared-generation.mjs +175 -0
  223. package/packages/orchestration/src/model-request-bounds.mjs +111 -0
  224. package/packages/orchestration/src/native-activity-contract.mjs +491 -0
  225. package/packages/orchestration/src/native-activity-service.mjs +102 -0
  226. package/packages/orchestration/src/native-activity-store.mjs +249 -0
  227. package/packages/orchestration/src/native-conversation-tools.mjs +78 -0
  228. package/packages/orchestration/src/native-data-tools.mjs +100 -0
  229. package/packages/orchestration/src/native-remote-actions.mjs +742 -0
  230. package/packages/orchestration/src/native-team-tools.mjs +73 -0
  231. package/packages/orchestration/src/pairing-invite.mjs +37 -0
  232. package/packages/orchestration/src/product-composition.mjs +1559 -1001
  233. package/packages/orchestration/src/remote-machines.mjs +82 -14
  234. package/packages/orchestration/src/routine-execution.mjs +5 -3
  235. package/packages/orchestration/src/routine-session.mjs +19 -13
  236. package/packages/orchestration/src/secure-pairing-host.mjs +112 -0
  237. package/packages/orchestration/src/task-journal.mjs +29 -0
  238. package/packages/orchestration/src/task-product.mjs +17 -0
  239. package/packages/orchestration/src/team-assignment-store.mjs +120 -0
  240. package/packages/orchestration/src/team-bridge.mjs +282 -0
  241. package/packages/orchestration/src/team-scheduler.mjs +83 -0
  242. package/packages/orchestration/src/team-sdk-tools.mjs +84 -0
  243. package/packages/orchestration/src/team-tool-contract.mjs +284 -0
  244. package/packages/orchestration/src/ui-host-namespace.mjs +23 -0
  245. package/packages/orchestration/src/web-panel-actions.mjs +103 -0
  246. package/packages/orchestration/src/web-panel-framing.mjs +227 -0
  247. package/packages/orchestration/src/web-panel-store.mjs +206 -0
  248. package/remote-computer-agent/README.md +39 -29
  249. package/remote-computer-agent/build.mjs +3 -0
  250. package/remote-computer-agent/dist/OPENMAUSBOT_LICENSE +202 -0
  251. package/remote-computer-agent/dist/OPENMAUSBOT_NOTICE +10 -0
  252. package/remote-computer-agent/dist/OPENMAUSBOT_SOURCE.json +68 -0
  253. package/remote-computer-agent/dist/cli-stdio-bridge.mjs +215 -25
  254. package/remote-computer-agent/dist/cli-stdio-bridge.mjs.map +4 -4
  255. package/remote-computer-agent/dist/cli.mjs +1688 -168
  256. package/remote-computer-agent/dist/cli.mjs.map +4 -4
  257. package/remote-computer-agent/dist/index.mjs +1579 -122
  258. package/remote-computer-agent/dist/index.mjs.map +4 -4
  259. package/remote-computer-agent/dist/native-peer.ps1 +51 -3
  260. package/remote-computer-agent/package-lock.json +308 -2
  261. package/remote-computer-agent/package.json +2 -1
  262. package/remote-computer-agent/pair-device.ps1 +20 -0
  263. package/remote-computer-agent/setup.ps1 +38 -16
  264. package/remote-computer-agent/src/cli.ts +24 -3
  265. package/remote-computer-agent/src/desktop-session.ts +11 -3
  266. package/remote-computer-agent/src/e2e-server.ts +81 -0
  267. package/remote-computer-agent/src/pairing-page.ts +35 -0
  268. package/remote-computer-agent/src/protocol.ts +25 -25
  269. package/remote-computer-agent/src/secure-pairing.ts +105 -0
  270. package/remote-computer-agent/src/store.ts +20 -5
  271. package/remote-computer-agent/src/transport.ts +39 -15
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Notification centre styles. Colour lives in the --bp-notif-* tokens below and
3
+ * follows one appearance: light is the default, the dark block only names what
4
+ * changes. Body text stays on the high-contrast ink; the category tone paints
5
+ * the leading rail and icon only, so a status never trades readability for hue.
6
+ */
7
+ html body[data-bot-product-ui] .bp-notifications {
8
+ --bp-notif-canvas: #f4f5f7;
9
+ --bp-notif-surface: #ffffff;
10
+ --bp-notif-inset: #eef0f3;
11
+ --bp-notif-hover: #e6e9ee;
12
+ --bp-notif-line: #dde1e8;
13
+ --bp-notif-ink: #252a33;
14
+ --bp-notif-muted: #5f6875;
15
+ --bp-notif-accent: #4a6484;
16
+ --bp-notif-accent-ink: #ffffff;
17
+ --bp-notif-focus: #4a6484;
18
+ --bp-notif-ok: #2e7d32;
19
+ --bp-notif-bad: #b3261e;
20
+ --bp-notif-urgent: #8a5a12;
21
+ --bp-notif-wait: #3f5d80;
22
+ --bp-notif-idle: #5f6875;
23
+ display: flex; flex-direction: column; min-height: 0; color: var(--bp-notif-ink);
24
+ background: var(--bp-notif-canvas);
25
+ }
26
+ html body[data-bot-product-ui][data-bp-appearance="dark"] .bp-notifications,
27
+ html body[data-bot-product-ui][data-ds-dark-theme]:not([data-bp-appearance="light"]) .bp-notifications {
28
+ --bp-notif-canvas: #131519;
29
+ --bp-notif-surface: #1c1f24;
30
+ --bp-notif-inset: #232730;
31
+ --bp-notif-hover: #2a2f39;
32
+ --bp-notif-line: #333a45;
33
+ --bp-notif-ink: #e8eaee;
34
+ --bp-notif-muted: #aab2bd;
35
+ --bp-notif-accent: #a9c4e0;
36
+ --bp-notif-accent-ink: #131519;
37
+ --bp-notif-focus: #a9c4e0;
38
+ --bp-notif-ok: #7bd48a;
39
+ --bp-notif-bad: #f2b8b5;
40
+ --bp-notif-urgent: #f6c76b;
41
+ --bp-notif-wait: #a9c4e0;
42
+ --bp-notif-idle: #aab2bd;
43
+ }
44
+
45
+ html body[data-bot-product-ui] .bp-notifications-bar {
46
+ display: flex; align-items: center; gap: 8px; padding: 12px 16px;
47
+ border-bottom: 1px solid var(--bp-notif-line); background: var(--bp-notif-surface);
48
+ }
49
+ html body[data-bot-product-ui] .bp-notifications-title { margin: 0; font-size: 15px; font-weight: 650; }
50
+ html body[data-bot-product-ui] .bp-notifications-badge {
51
+ min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
52
+ background: var(--bp-notif-bad); color: #ffffff; font-size: 12px; font-weight: 700;
53
+ display: inline-flex; align-items: center; justify-content: center;
54
+ }
55
+ html body[data-bot-product-ui][data-bp-appearance="dark"] .bp-notifications-badge,
56
+ html body[data-bot-product-ui][data-ds-dark-theme]:not([data-bp-appearance="light"]) .bp-notifications-badge { color: #131519; }
57
+ html body[data-bot-product-ui] .bp-notifications-bar-actions { margin-left: auto; }
58
+ html body[data-bot-product-ui] .bp-notifications-markall {
59
+ display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 12px;
60
+ border: 1px solid var(--bp-notif-line); border-radius: 8px; background: var(--bp-notif-inset);
61
+ color: var(--bp-notif-ink); font-size: 13px; cursor: pointer;
62
+ }
63
+ html body[data-bot-product-ui] .bp-notifications-markall:hover:not(:disabled) { background: var(--bp-notif-hover); }
64
+ html body[data-bot-product-ui] .bp-notifications-markall:disabled { opacity: 0.5; cursor: default; }
65
+
66
+ html body[data-bot-product-ui] .bp-notifications-note { margin: 0; padding: 20px 16px; color: var(--bp-notif-muted); font-size: 13px; }
67
+
68
+ html body[data-bot-product-ui] .bp-notifications-list { list-style: none; margin: 0; padding: 8px; display: flex; flex-direction: column; gap: 6px; overflow-y: auto; }
69
+ html body[data-bot-product-ui] .bp-notification {
70
+ position: relative; display: flex; align-items: stretch; gap: 4px;
71
+ background: var(--bp-notif-surface); border: 1px solid var(--bp-notif-line); border-radius: 10px;
72
+ border-left: 3px solid var(--bp-notif-idle);
73
+ }
74
+ html body[data-bot-product-ui] .bp-notification-ok { border-left-color: var(--bp-notif-ok); }
75
+ html body[data-bot-product-ui] .bp-notification-bad { border-left-color: var(--bp-notif-bad); }
76
+ html body[data-bot-product-ui] .bp-notification-urgent { border-left-color: var(--bp-notif-urgent); }
77
+ html body[data-bot-product-ui] .bp-notification-wait { border-left-color: var(--bp-notif-wait); }
78
+ html body[data-bot-product-ui] .bp-notification-ok .bp-notification-icon { color: var(--bp-notif-ok); }
79
+ html body[data-bot-product-ui] .bp-notification-bad .bp-notification-icon { color: var(--bp-notif-bad); }
80
+ html body[data-bot-product-ui] .bp-notification-urgent .bp-notification-icon { color: var(--bp-notif-urgent); }
81
+ html body[data-bot-product-ui] .bp-notification-wait .bp-notification-icon { color: var(--bp-notif-wait); }
82
+ html body[data-bot-product-ui] .bp-notification-idle .bp-notification-icon { color: var(--bp-notif-idle); }
83
+
84
+ html body[data-bot-product-ui] .bp-notification-open {
85
+ flex: 1; display: flex; align-items: flex-start; justify-content: flex-start; gap: 10px; padding: 12px; min-height: 40px;
86
+ background: none; border: 0; border-radius: 8px; text-align: left; color: inherit; cursor: pointer; font: inherit;
87
+ }
88
+ html body[data-bot-product-ui] .bp-notification-open:hover { background: var(--bp-notif-hover); }
89
+ html body[data-bot-product-ui] .bp-notification-icon { display: inline-flex; padding-top: 1px; }
90
+ html body[data-bot-product-ui] .bp-notification-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
91
+ html body[data-bot-product-ui] .bp-notification-text { font-size: 14px; line-height: 1.35; }
92
+ html body[data-bot-product-ui] .bp-notification-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--bp-notif-muted); }
93
+ html body[data-bot-product-ui] .bp-notification-new {
94
+ padding: 0 6px; border-radius: 999px; background: var(--bp-notif-accent); color: var(--bp-notif-accent-ink); font-size: 11px; font-weight: 700;
95
+ }
96
+ html body[data-bot-product-ui] .bp-notification-dot { width: 8px; height: 8px; margin-top: 14px; border-radius: 999px; background: var(--bp-notif-accent); flex: none; }
97
+ html body[data-bot-product-ui] .bp-notification-read {
98
+ display: inline-flex; align-items: center; justify-content: center; width: 40px; flex: none;
99
+ border: 0; border-left: 1px solid var(--bp-notif-line); border-radius: 0 8px 8px 0;
100
+ background: none; color: var(--bp-notif-muted); cursor: pointer;
101
+ }
102
+ html body[data-bot-product-ui] .bp-notification-read:hover { background: var(--bp-notif-hover); color: var(--bp-notif-ink); }
103
+
104
+ html body[data-bot-product-ui] .bp-notifications-more {
105
+ margin: 4px 8px 12px; min-height: 36px; border: 1px solid var(--bp-notif-line); border-radius: 8px;
106
+ background: var(--bp-notif-surface); color: var(--bp-notif-ink); font-size: 13px; cursor: pointer;
107
+ }
108
+ html body[data-bot-product-ui] .bp-notifications-more:disabled { opacity: 0.6; cursor: default; }
109
+
110
+ html body[data-bot-product-ui] .bp-notifications :is(button):focus-visible {
111
+ outline: 2px solid var(--bp-notif-focus); outline-offset: 1px;
112
+ }
113
+
114
+ /* A phone keeps every row full-width and comfortable at 375px. */
115
+ @media (max-width: 640px) {
116
+ html body[data-bot-product-ui] .bp-notifications-bar { padding: 10px 12px; }
117
+ html body[data-bot-product-ui] .bp-notifications-list { padding: 6px; }
118
+ html body[data-bot-product-ui] .bp-notification-open { padding: 10px; }
119
+ html body[data-bot-product-ui] .bp-notifications-markall span { display: none; }
120
+ }
121
+
122
+ /* Touch: every control reaches a 40px target and nothing depends on hover. */
123
+ @media (pointer: coarse) {
124
+ html body[data-bot-product-ui] .bp-notifications-markall { min-width: 40px; min-height: 40px; }
125
+ html body[data-bot-product-ui] .bp-notification-read { width: 44px; }
126
+ }
@@ -0,0 +1,79 @@
1
+ import React,{useEffect,useRef,useState} from 'react'
2
+ import jsQR from 'jsqr'
3
+ import {parseSecureInvite} from '../../packages/orchestration/src/pairing-invite.mjs'
4
+
5
+ export function readPairingPixels(data,width,height){
6
+ if(!(data instanceof Uint8ClampedArray)||!Number.isInteger(width)||!Number.isInteger(height)||width<1||height<1||width*height>4_000_000||data.length!==width*height*4)throw new Error('二维码图片尺寸无效。')
7
+ const code=jsQR(data,width,height,{inversionAttempts:'attemptBoth'})
8
+ if(!code)throw new Error('没有识别到二维码,请使用清晰完整的配对二维码。')
9
+ const invite=parseSecureInvite(code.data)
10
+ return JSON.stringify(invite)
11
+ }
12
+
13
+ /** Image decoding stays local. Camera access starts only after an explicit scan click. */
14
+ export function PairingQrReader({onRead,disabled=false}){
15
+ const [scanning,setScanning]=useState(false),[error,setError]=useState(''),[reading,setReading]=useState(false)
16
+ const generation=useRef(0),video=useRef(null),camera=useRef(null),timer=useRef(null),dialog=useRef(null),trigger=useRef(null),imageInput=useRef(null),mounted=useRef(true),onReadRef=useRef(onRead)
17
+ onReadRef.current=onRead
18
+ const stop=()=>{generation.current++;clearTimeout(timer.current);timer.current=null;for(const track of camera.current?.getTracks?.()??[])track.stop();camera.current=null;if(video.current)video.current.srcObject=null}
19
+ const close=()=>{stop();setScanning(false);trigger.current?.focus()}
20
+ useEffect(()=>{mounted.current=true;return()=>{mounted.current=false;stop()}},[])
21
+ useEffect(()=>{if(disabled){stop();setScanning(false);setReading(false)}},[disabled])
22
+ useEffect(()=>{
23
+ const hidden=()=>{if(document.hidden){stop();setScanning(false)}}
24
+ document.addEventListener('visibilitychange',hidden);return()=>document.removeEventListener('visibilitychange',hidden)
25
+ },[])
26
+ useEffect(()=>{
27
+ if(!scanning)return
28
+ const active=++generation.current,canvas=document.createElement('canvas'),context=canvas.getContext('2d',{willReadFrequently:true})
29
+ const fail=message=>{if(mounted.current&&generation.current===active){stop();setError(message);setScanning(false);trigger.current?.focus()}}
30
+ const tick=()=>{
31
+ if(!mounted.current||generation.current!==active)return
32
+ const source=video.current
33
+ if(source?.readyState>=2&&source.videoWidth){
34
+ const scale=Math.min(1,1200/Math.max(source.videoWidth,source.videoHeight));canvas.width=Math.max(1,Math.round(source.videoWidth*scale));canvas.height=Math.max(1,Math.round(source.videoHeight*scale))
35
+ context.drawImage(source,0,0,canvas.width,canvas.height)
36
+ try{const value=readPairingPixels(context.getImageData(0,0,canvas.width,canvas.height).data,canvas.width,canvas.height);stop();setScanning(false);onReadRef.current(value);trigger.current?.focus();return}catch{}
37
+ }
38
+ timer.current=setTimeout(tick,180)
39
+ }
40
+ const start=async()=>{
41
+ try{
42
+ if(!context||!navigator.mediaDevices?.getUserMedia)throw new Error('当前环境无法开启摄像头,请改用二维码图片或邀请码。')
43
+ const stream=await navigator.mediaDevices.getUserMedia({audio:false,video:{facingMode:{ideal:'environment'},width:{ideal:1280}}})
44
+ if(!mounted.current||generation.current!==active){for(const track of stream.getTracks())track.stop();return}
45
+ camera.current=stream;video.current.srcObject=stream;await video.current.play()
46
+ if(generation.current===active)tick()
47
+ }catch(failure){fail(failure.name==='NotAllowedError'?'摄像头未获允许,可以改用二维码图片或邀请码。':String(failure.message??failure))}
48
+ }
49
+ dialog.current?.querySelector('button')?.focus();void start()
50
+ return()=>{if(generation.current===active)stop()}
51
+ },[scanning])
52
+ const image=async event=>{
53
+ const file=event.target.files?.[0];event.target.value='';if(!file)return
54
+ stop();setScanning(false);setReading(true);setError('');const active=generation.current
55
+ try{
56
+ if(file.size>10*1024*1024||!['image/png','image/jpeg','image/webp'].includes(file.type))throw new Error('请选择不超过 10 MB 的 PNG、JPEG 或 WebP 二维码图片。')
57
+ const bitmap=await createImageBitmap(file)
58
+ try{
59
+ if(!mounted.current||active!==generation.current)return
60
+ const scale=Math.min(1,1800/Math.max(bitmap.width,bitmap.height)),canvas=document.createElement('canvas')
61
+ canvas.width=Math.max(1,Math.round(bitmap.width*scale));canvas.height=Math.max(1,Math.round(bitmap.height*scale))
62
+ const context=canvas.getContext('2d',{willReadFrequently:true});if(!context)throw new Error('当前环境无法读取图片,请粘贴邀请码。')
63
+ context.drawImage(bitmap,0,0,canvas.width,canvas.height)
64
+ const value=readPairingPixels(context.getImageData(0,0,canvas.width,canvas.height).data,canvas.width,canvas.height)
65
+ onReadRef.current(value)
66
+ }finally{bitmap.close()}
67
+ }catch(failure){if(mounted.current&&active===generation.current)setError(failure.code?'这不是受支持的设备配对二维码。':String(failure.message??failure))}
68
+ finally{if(mounted.current&&active===generation.current)setReading(false)}
69
+ }
70
+ return <div className="bp-pairing-reader"><div className="bp-actions"><button ref={trigger} type="button" disabled={disabled||reading} onClick={()=>{setError('');setScanning(true)}}>扫描配对二维码</button>
71
+ <button type="button" disabled={disabled||reading} onClick={()=>imageInput.current?.click()}>{reading?'正在识别…':'导入二维码图片'}</button>
72
+ <input ref={imageInput} className="bp-pairing-file" aria-label="二维码图片" type="file" accept="image/png,image/jpeg,image/webp" disabled={disabled||reading} onChange={event=>{void image(event)}}/></div>
73
+ {error&&<p className="bp-error" role="alert">{error}</p>}
74
+ {scanning&&<div className="bp-pairing-camera-overlay" role="dialog" aria-modal="true" aria-label="扫描电脑配对二维码" ref={dialog} onKeyDown={event=>{
75
+ if(event.key==='Escape'&&!event.nativeEvent.isComposing&&event.nativeEvent.keyCode!==229){event.preventDefault();close()}
76
+ if(event.key==='Tab'){event.preventDefault();dialog.current?.querySelector('button')?.focus()}
77
+ }}><section className="bp-pairing-camera"><header><strong>扫描电脑上的配对二维码</strong><button type="button" onClick={close}>关闭摄像头</button></header><video ref={video} muted playsInline/><p>将完整二维码放入画面,识别后仍需核对设备指纹和六位确认码。</p></section></div>}
78
+ </div>
79
+ }