@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.
- package/.dsh-plugin/bot-product.mjs +81 -5
- package/.dsh-plugin/client.js +17490 -1791
- package/README.i18n.yaml +4 -4
- package/README.md +409 -364
- package/README.zh.md +409 -364
- package/apps/integration-client/README.md +31 -7
- package/apps/integration-client/api.mjs +14 -3
- package/apps/integration-client/binding-editor.jsx +308 -109
- package/apps/integration-client/binding-model.mjs +262 -0
- package/apps/integration-client/binding.css +144 -0
- package/apps/integration-client/bot-model-status.mjs +18 -0
- package/apps/integration-client/bot-profile-identity.jsx +197 -0
- package/apps/integration-client/bot-profile.css +57 -0
- package/apps/integration-client/bot-profile.mjs +97 -0
- package/apps/integration-client/bot-settings-dialog.css +18 -0
- package/apps/integration-client/bot-settings-dialog.jsx +111 -0
- package/apps/integration-client/bot-thread-header-bridge.css +20 -0
- package/apps/integration-client/bot-thread-header.jsx +278 -0
- package/apps/integration-client/bot-threads-panel.jsx +378 -0
- package/apps/integration-client/bot-threads.css +169 -0
- package/apps/integration-client/chat-design.mjs +250 -0
- package/apps/integration-client/chat-ui.jsx +175 -0
- package/apps/integration-client/chat.css +477 -0
- package/apps/integration-client/composer-draft-binding.mjs +50 -0
- package/apps/integration-client/composer-draft-bound.jsx +14 -0
- package/apps/integration-client/composer-draft-host.jsx +142 -0
- package/apps/integration-client/composer-draft-session.jsx +287 -0
- package/apps/integration-client/composer-draft-witness.mjs +115 -0
- package/apps/integration-client/composer-draft.css +4 -0
- package/apps/integration-client/composer-draft.mjs +322 -0
- package/apps/integration-client/contact-attention.jsx +54 -0
- package/apps/integration-client/data-panel.jsx +439 -0
- package/apps/integration-client/data.css +69 -0
- package/apps/integration-client/desktop-bridge.mjs +1 -0
- package/apps/integration-client/desktop-http-socket.mjs +49 -0
- package/apps/integration-client/desktop-keyboard.mjs +32 -0
- package/apps/integration-client/desktop-pane.jsx +99 -30
- package/apps/integration-client/desktop-stream.mjs +13 -3
- package/apps/integration-client/desktop-tools.jsx +19 -0
- package/apps/integration-client/desktop-touch.mjs +27 -0
- package/apps/integration-client/desktop.css +41 -0
- package/apps/integration-client/independent-chat-controller.mjs +224 -0
- package/apps/integration-client/independent-chat-entry.jsx +61 -0
- package/apps/integration-client/independent-chat-navigation.mjs +21 -0
- package/apps/integration-client/independent-chat-page.jsx +148 -0
- package/apps/integration-client/independent-chat-rich.jsx +64 -0
- package/apps/integration-client/independent-chat-rich.mjs +30 -0
- package/apps/integration-client/independent-chat.css +73 -0
- package/apps/integration-client/index.jsx +24 -16
- package/apps/integration-client/library-panel.jsx +4 -1
- package/apps/integration-client/licenses/jsqr-1.4.0-LICENSE.txt +202 -0
- package/apps/integration-client/main-route-editor.jsx +94 -0
- package/apps/integration-client/main-route-model.mjs +100 -0
- package/apps/integration-client/model-picker.css +37 -0
- package/apps/integration-client/model-picker.jsx +83 -0
- package/apps/integration-client/native-activity.css +141 -0
- package/apps/integration-client/native-activity.jsx +276 -0
- package/apps/integration-client/native-activity.mjs +384 -0
- package/apps/integration-client/notifications-panel.jsx +186 -0
- package/apps/integration-client/notifications.css +126 -0
- package/apps/integration-client/pairing-qr.jsx +79 -0
- package/apps/integration-client/panels.jsx +126 -115
- package/apps/integration-client/product-slots.jsx +46 -0
- package/apps/integration-client/routine-recorder.mjs +23 -2
- package/apps/integration-client/secure-pairing.jsx +84 -0
- package/apps/integration-client/tasks-panel.jsx +32 -10
- package/apps/integration-client/ui-icons.jsx +17 -0
- package/apps/integration-client/usage-explorer.jsx +43 -0
- package/apps/integration-client/usage-report.mjs +71 -0
- package/apps/integration-client/usage.css +34 -0
- package/apps/integration-client/web-panel-model.mjs +140 -0
- package/apps/integration-client/web-panel-page.jsx +221 -0
- package/apps/integration-client/web-panel-pins-live.jsx +28 -0
- package/apps/integration-client/web-panel.css +139 -0
- package/apps/integration-client/workspace-model.mjs +67 -0
- package/apps/integration-client/workspace-navigation.mjs +56 -0
- package/apps/integration-client/workspace-ui.jsx +173 -0
- package/apps/integration-client/workspace.css +332 -0
- package/modules/bot-runtime/SOURCE.json +176 -50
- package/modules/bot-runtime/index.mjs +169 -13
- package/modules/bot-runtime/product-overlay/OVERLAY.json +128 -2
- package/modules/bot-runtime/product-overlay/base/src/client/header.js +244 -0
- package/modules/bot-runtime/product-overlay/base/src/client/learning-card.js +202 -0
- package/modules/bot-runtime/product-overlay/base/src/client/model-menu.js +371 -0
- package/modules/bot-runtime/product-overlay/base/src/client/secret-card.js +363 -0
- package/modules/bot-runtime/product-overlay/base/src/client/sources.js +68 -0
- package/modules/bot-runtime/product-overlay/base/src/client/turn-error.js +260 -0
- package/modules/bot-runtime/product-overlay/base/src/host/channel.js +647 -0
- package/modules/bot-runtime/product-overlay/base/src/host/memory.js +2050 -0
- package/modules/bot-runtime/product-overlay/base/src/host/models.js +314 -0
- package/modules/bot-runtime/product-overlay/base/src/host/parts.js +1473 -0
- package/modules/bot-runtime/product-overlay/base/src/host/privacy.js +368 -0
- package/modules/bot-runtime/product-overlay/base/src/host/roster.js +776 -0
- package/modules/bot-runtime/product-overlay/base/src/host/store.js +512 -0
- package/modules/bot-runtime/product-overlay/base/src/host/usage.js +653 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/details-drawer.js.patch +48 -2
- package/modules/bot-runtime/product-overlay/patches/src/client/header.js.patch +41 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/index.js.patch +33 -1
- package/modules/bot-runtime/product-overlay/patches/src/client/learning-card.js.patch +20 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/model-menu.js.patch +24 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/secret-card.js.patch +25 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/sources.js.patch +52 -0
- package/modules/bot-runtime/product-overlay/patches/src/client/turn-error.js.patch +23 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/channel.js.patch +46 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/memory.js.patch +11 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/models.js.patch +16 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/parts.js.patch +95 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/privacy.js.patch +11 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/roster.js.patch +145 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/store.js.patch +68 -0
- package/modules/bot-runtime/product-overlay/patches/src/host/usage.js.patch +11 -0
- package/modules/bot-runtime/read-model.mjs +19 -4
- package/modules/bot-runtime/vendor/ds-bot/src/client/details-drawer.js +15 -5
- package/modules/bot-runtime/vendor/ds-bot/src/client/header.js +9 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/index.js +9 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/learning-card.js +2 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/model-menu.js +5 -3
- package/modules/bot-runtime/vendor/ds-bot/src/client/secret-card.js +3 -3
- package/modules/bot-runtime/vendor/ds-bot/src/client/sources.js +25 -2
- package/modules/bot-runtime/vendor/ds-bot/src/client/turn-error.js +3 -2
- package/modules/bot-runtime/vendor/ds-bot/src/host/channel.js +14 -2
- package/modules/bot-runtime/vendor/ds-bot/src/host/memory.js +1 -1
- package/modules/bot-runtime/vendor/ds-bot/src/host/models.js +7 -0
- package/modules/bot-runtime/vendor/ds-bot/src/host/parts.js +26 -9
- package/modules/bot-runtime/vendor/ds-bot/src/host/privacy.js +1 -1
- package/modules/bot-runtime/vendor/ds-bot/src/host/roster.js +112 -3
- package/modules/bot-runtime/vendor/ds-bot/src/host/store.js +34 -1
- package/modules/bot-runtime/vendor/ds-bot/src/host/usage.js +1 -1
- package/modules/independent-runtime/index.mjs +152 -62
- package/modules/independent-runtime/remote-tools.mjs +8 -5
- package/modules/openmaus-protocol/NOTICE +10 -0
- package/modules/openmaus-protocol/README.md +15 -0
- package/modules/openmaus-protocol/SOURCE.json +68 -0
- package/modules/openmaus-protocol/dist/protocol.mjs +1203 -0
- package/modules/openmaus-protocol/index.mjs +1 -0
- package/modules/openmaus-protocol/transport.mjs +77 -0
- package/modules/openmaus-protocol/vendor/LICENSE +202 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/README.md +405 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/credentials.ts +128 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/descriptor.ts +84 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/noise.ts +456 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/phone.ts +104 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/session.ts +417 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.json +2565 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.sha256 +1 -0
- package/modules/openmaus-protocol/vendor/companion/src/e2e/yamux.ts +335 -0
- package/package.json +18 -6
- package/packages/bot-acp/README.md +156 -0
- package/packages/bot-acp/licenses/LICENSE-OpenMausBot +202 -0
- package/packages/bot-acp/licenses/NOTICE.md +27 -0
- package/packages/bot-acp/src/acp-adapter.mjs +795 -0
- package/packages/bot-acp/src/acp-host.mjs +148 -0
- package/packages/bot-acp/src/native-launch.mjs +121 -0
- package/packages/bot-acp/src/permission-policy.mjs +283 -0
- package/packages/bot-acp/src/rpc-codec.mjs +265 -0
- package/packages/bot-acp/src/session-core.mjs +581 -0
- package/packages/bot-acp/src/stdio-rpc.mjs +329 -0
- package/packages/bot-engines/README.md +281 -0
- package/packages/bot-engines/licenses/LICENSE-OpenMausBot +202 -0
- package/packages/bot-engines/licenses/NOTICE.md +32 -0
- package/packages/bot-engines/src/claude-engine.mjs +772 -0
- package/packages/bot-engines/src/claude-llm-adapter.mjs +797 -0
- package/packages/bot-engines/src/claude-llm-turn.mjs +292 -0
- package/packages/bot-engines/src/claude-permission-broker.mjs +130 -0
- package/packages/bot-engines/src/claude-permission-proxy.mjs +87 -0
- package/packages/bot-engines/src/claude-protocol.mjs +177 -0
- package/packages/bot-engines/src/driver-catalog.mjs +334 -0
- package/packages/bot-engines/src/host-loop-request.mjs +95 -0
- package/packages/bot-engines/src/host-registrations.mjs +105 -0
- package/packages/capability-broker/src/cli-bootstrap.mjs +86 -16
- package/packages/capability-broker/src/cli-bridge-response.mjs +80 -0
- package/packages/capability-broker/src/cli-stdio-bridge.mjs +21 -8
- package/packages/cli-runtime/src/codex-session-core.mjs +4 -0
- package/packages/cli-runtime/src/native-cli-output.mjs +57 -0
- package/packages/cli-runtime/src/native-peer.ps1 +51 -3
- package/packages/cli-runtime/src/native-process.mjs +77 -14
- package/packages/model-router-plugin/package.json +1 -1
- package/packages/orchestration/src/binding-product.mjs +19 -0
- package/packages/orchestration/src/bot-data-actions.mjs +45 -0
- package/packages/orchestration/src/bot-data-chart.mjs +109 -0
- package/packages/orchestration/src/bot-data-context.mjs +44 -0
- package/packages/orchestration/src/bot-data-engine.mjs +809 -0
- package/packages/orchestration/src/bot-data-io.mjs +186 -0
- package/packages/orchestration/src/bot-data-sql.mjs +195 -0
- package/packages/orchestration/src/bot-data-surface.mjs +144 -0
- package/packages/orchestration/src/bot-data-tools.mjs +68 -0
- package/packages/orchestration/src/bot-data-worker.mjs +228 -0
- package/packages/orchestration/src/bot-independent-execution.mjs +195 -0
- package/packages/orchestration/src/bot-independent-stream.mjs +74 -0
- package/packages/orchestration/src/bot-loop.mjs +152 -19
- package/packages/orchestration/src/bot-notifications.mjs +159 -0
- package/packages/orchestration/src/bot-policy.mjs +43 -4
- package/packages/orchestration/src/bot-profile.mjs +171 -0
- package/packages/orchestration/src/bot-routine.mjs +4 -4
- package/packages/orchestration/src/bot-runtime-assembly.mjs +255 -8
- package/packages/orchestration/src/bot-runtime-switch.mjs +13 -2
- package/packages/orchestration/src/bot-serving.mjs +164 -0
- package/packages/orchestration/src/bot-session-store.mjs +105 -9
- package/packages/orchestration/src/bot-settings.mjs +50 -11
- package/packages/orchestration/src/bot-thread-admission.mjs +84 -0
- package/packages/orchestration/src/bot-thread-host.mjs +187 -0
- package/packages/orchestration/src/bot-threads.mjs +790 -0
- package/packages/orchestration/src/data-product-access.mjs +37 -0
- package/packages/orchestration/src/data-tool-contract.mjs +291 -0
- package/packages/orchestration/src/desktop-http-carrier.mjs +120 -0
- package/packages/orchestration/src/desktop-proxy.mjs +311 -0
- package/packages/orchestration/src/desktop-sessions.mjs +43 -9
- package/packages/orchestration/src/ds-lifecycle.mjs +31 -4
- package/packages/orchestration/src/grant-refresh-queue.mjs +17 -0
- package/packages/orchestration/src/independent-chat-page.mjs +39 -0
- package/packages/orchestration/src/independent-chat-service.mjs +308 -0
- package/packages/orchestration/src/independent-context-state.mjs +44 -0
- package/packages/orchestration/src/independent-message-wire.mjs +84 -0
- package/packages/orchestration/src/independent-tool-catalog.mjs +175 -0
- package/packages/orchestration/src/independent-tool-families.mjs +73 -0
- package/packages/orchestration/src/independent-tool-host.mjs +344 -0
- package/packages/orchestration/src/main-bot-grant.mjs +15 -0
- package/packages/orchestration/src/main-model-routes.mjs +208 -0
- package/packages/orchestration/src/model-accounting.mjs +99 -35
- package/packages/orchestration/src/model-auxiliary-dispatch.mjs +187 -0
- package/packages/orchestration/src/model-loop-frame.mjs +179 -0
- package/packages/orchestration/src/model-prepared-generation.mjs +175 -0
- package/packages/orchestration/src/model-request-bounds.mjs +111 -0
- package/packages/orchestration/src/native-activity-contract.mjs +491 -0
- package/packages/orchestration/src/native-activity-service.mjs +102 -0
- package/packages/orchestration/src/native-activity-store.mjs +249 -0
- package/packages/orchestration/src/native-conversation-tools.mjs +78 -0
- package/packages/orchestration/src/native-data-tools.mjs +100 -0
- package/packages/orchestration/src/native-remote-actions.mjs +742 -0
- package/packages/orchestration/src/native-team-tools.mjs +73 -0
- package/packages/orchestration/src/pairing-invite.mjs +37 -0
- package/packages/orchestration/src/product-composition.mjs +1559 -1001
- package/packages/orchestration/src/remote-machines.mjs +82 -14
- package/packages/orchestration/src/routine-execution.mjs +5 -3
- package/packages/orchestration/src/routine-session.mjs +19 -13
- package/packages/orchestration/src/secure-pairing-host.mjs +112 -0
- package/packages/orchestration/src/task-journal.mjs +29 -0
- package/packages/orchestration/src/task-product.mjs +17 -0
- package/packages/orchestration/src/team-assignment-store.mjs +120 -0
- package/packages/orchestration/src/team-bridge.mjs +282 -0
- package/packages/orchestration/src/team-scheduler.mjs +83 -0
- package/packages/orchestration/src/team-sdk-tools.mjs +84 -0
- package/packages/orchestration/src/team-tool-contract.mjs +284 -0
- package/packages/orchestration/src/ui-host-namespace.mjs +23 -0
- package/packages/orchestration/src/web-panel-actions.mjs +103 -0
- package/packages/orchestration/src/web-panel-framing.mjs +227 -0
- package/packages/orchestration/src/web-panel-store.mjs +206 -0
- package/remote-computer-agent/README.md +39 -29
- package/remote-computer-agent/build.mjs +3 -0
- package/remote-computer-agent/dist/OPENMAUSBOT_LICENSE +202 -0
- package/remote-computer-agent/dist/OPENMAUSBOT_NOTICE +10 -0
- package/remote-computer-agent/dist/OPENMAUSBOT_SOURCE.json +68 -0
- package/remote-computer-agent/dist/cli-stdio-bridge.mjs +215 -25
- package/remote-computer-agent/dist/cli-stdio-bridge.mjs.map +4 -4
- package/remote-computer-agent/dist/cli.mjs +1688 -168
- package/remote-computer-agent/dist/cli.mjs.map +4 -4
- package/remote-computer-agent/dist/index.mjs +1579 -122
- package/remote-computer-agent/dist/index.mjs.map +4 -4
- package/remote-computer-agent/dist/native-peer.ps1 +51 -3
- package/remote-computer-agent/package-lock.json +308 -2
- package/remote-computer-agent/package.json +2 -1
- package/remote-computer-agent/pair-device.ps1 +20 -0
- package/remote-computer-agent/setup.ps1 +38 -16
- package/remote-computer-agent/src/cli.ts +24 -3
- package/remote-computer-agent/src/desktop-session.ts +11 -3
- package/remote-computer-agent/src/e2e-server.ts +81 -0
- package/remote-computer-agent/src/pairing-page.ts +35 -0
- package/remote-computer-agent/src/protocol.ts +25 -25
- package/remote-computer-agent/src/secure-pairing.ts +105 -0
- package/remote-computer-agent/src/store.ts +20 -5
- package/remote-computer-agent/src/transport.ts +39 -15
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
/* The Bot conversation surface: contacts, transcript, composer.
|
|
2
|
+
*
|
|
3
|
+
* Scope. Every rule hangs off body[data-bot-product-ui], so the Harness
|
|
4
|
+
* workbench, other Sessions and the plain Agent view keep their own styling.
|
|
5
|
+
* The product islands (.bp-contact-*, .bp-conversation-tools) carry the product's
|
|
6
|
+
* own controls; the .bt-* rules restyle DS Bot 0.2.7's native conversation DOM
|
|
7
|
+
* without changing its structure, so sending, stopping, approvals and session
|
|
8
|
+
* switching stay exactly where the native components put them.
|
|
9
|
+
*
|
|
10
|
+
* Beating the vendor. DS Bot's SHELL_CSS/CONVERSATION_CSS land in <head> after
|
|
11
|
+
* this sheet (index.jsx appends ours, then applyDs installs the vendor's), and it
|
|
12
|
+
* pins a number of properties with !important. Two consequences, both deliberate:
|
|
13
|
+
* - a rule that competes with a vendor rule needs more specificity than it, not
|
|
14
|
+
* just a later position — hence the body[data-bot-product-ui] prefix on all
|
|
15
|
+
* of them;
|
|
16
|
+
* - where the vendor pins the very property this design changes (the header
|
|
17
|
+
* band, the composer surface, the shell's own user bubble), this sheet uses
|
|
18
|
+
* !important with a selector that outranks it. Layout and the submit/stop
|
|
19
|
+
* controls are never overridden.
|
|
20
|
+
*
|
|
21
|
+
* Colour lives in the --bp-chat-* tokens below and is checked by
|
|
22
|
+
* chat-design.mjs: text 4.5:1, rings and borders 3:1, hairlines merely visible.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
html body[data-bot-product-ui],
|
|
26
|
+
html body[data-bot-product-ui][data-bp-appearance],
|
|
27
|
+
html body[data-bot-product-ui][data-ds-dark-theme] {
|
|
28
|
+
/* Light is the default; the dark block below only names what changes. */
|
|
29
|
+
--bp-chat-canvas: #fcfcfd;
|
|
30
|
+
--bp-chat-surface: #ffffff;
|
|
31
|
+
--bp-chat-sidebar: #f4f5f7;
|
|
32
|
+
--bp-chat-inset: #eef0f3;
|
|
33
|
+
--bp-chat-hover: #e6e9ee;
|
|
34
|
+
--bp-chat-line: #dde1e8;
|
|
35
|
+
--bp-chat-line-strong: #7f8691;
|
|
36
|
+
--bp-chat-ink: #252a33;
|
|
37
|
+
--bp-chat-muted: #5f6875;
|
|
38
|
+
--bp-chat-accent: #4a6484;
|
|
39
|
+
--bp-chat-accent-ink: #ffffff;
|
|
40
|
+
--bp-chat-focus: #4a6484;
|
|
41
|
+
--bp-chat-user: #2b3444;
|
|
42
|
+
--bp-chat-on-user: #ffffff;
|
|
43
|
+
--bp-chat-danger: #b3261e;
|
|
44
|
+
--bp-chat-danger-bg: #fbe9e7;
|
|
45
|
+
--bp-chat-warning: #8a5a12;
|
|
46
|
+
--bp-chat-warning-bg: #faf1de;
|
|
47
|
+
--bp-chat-shadow: 0 1px 2px #252a3308, 0 8px 24px -12px #252a3321;
|
|
48
|
+
--bp-chat-shadow-float: 0 2px 6px -2px #252a3314, 0 18px 40px -20px #252a332e;
|
|
49
|
+
/* A bubble keeps a readable measure and leaves the reply its own column. */
|
|
50
|
+
--bt-msg-w: .78;
|
|
51
|
+
--bt-flat-w: 1;
|
|
52
|
+
/* The vendor's tokens, read out of the chat palette so every native control
|
|
53
|
+
follows one appearance. */
|
|
54
|
+
--bt-main: var(--bp-chat-canvas);
|
|
55
|
+
--bt-sidebar: var(--bp-chat-sidebar);
|
|
56
|
+
--bt-card: var(--bp-chat-surface);
|
|
57
|
+
--bt-bubble: var(--bp-chat-surface);
|
|
58
|
+
--bt-hover: var(--bp-chat-hover);
|
|
59
|
+
--bt-active: color-mix(in srgb, var(--bp-chat-accent) 13%, var(--bp-chat-inset));
|
|
60
|
+
--bt-ink: var(--bp-chat-ink);
|
|
61
|
+
--bt-ink-2: var(--bp-chat-muted);
|
|
62
|
+
--bt-ink-3: var(--bp-chat-muted);
|
|
63
|
+
--bt-line: var(--bp-chat-line);
|
|
64
|
+
--bt-line-2: var(--bp-chat-line-strong);
|
|
65
|
+
--bt-line-weak: var(--bp-chat-line);
|
|
66
|
+
--bt-accent: var(--bp-chat-accent);
|
|
67
|
+
--bt-accent-ink: var(--bp-chat-accent-ink);
|
|
68
|
+
--bt-user: var(--bp-chat-user);
|
|
69
|
+
--bt-user-ink: var(--bp-chat-on-user);
|
|
70
|
+
--bt-tag-bg: var(--bp-chat-inset);
|
|
71
|
+
--bt-tag-ink: var(--bp-chat-muted);
|
|
72
|
+
--bt-danger: var(--bp-chat-danger);
|
|
73
|
+
/* Whatever still reaches for glass (reaction strip, the pill before this sheet
|
|
74
|
+
restyles it) reads as an opaque chat surface, not a blur. */
|
|
75
|
+
--bt-glass-bg: var(--bp-chat-surface);
|
|
76
|
+
--bt-glass-border: var(--bp-chat-line);
|
|
77
|
+
--bt-glass-rim: var(--bp-chat-line);
|
|
78
|
+
--bt-glass-shadow: var(--bp-chat-shadow);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
html body[data-bot-product-ui][data-ds-dark-theme]:not([data-bp-appearance=light]),
|
|
82
|
+
html body[data-bot-product-ui][data-bp-appearance=dark] {
|
|
83
|
+
--bp-chat-canvas: #131519;
|
|
84
|
+
--bp-chat-surface: #1c1f25;
|
|
85
|
+
--bp-chat-sidebar: #191c21;
|
|
86
|
+
--bp-chat-inset: #23262d;
|
|
87
|
+
--bp-chat-hover: #2b2f38;
|
|
88
|
+
--bp-chat-line: #333842;
|
|
89
|
+
--bp-chat-line-strong: #878f9b;
|
|
90
|
+
--bp-chat-ink: #eef1f6;
|
|
91
|
+
--bp-chat-muted: #a2abb9;
|
|
92
|
+
--bp-chat-accent: #a9c3e2;
|
|
93
|
+
--bp-chat-accent-ink: #1b2231;
|
|
94
|
+
--bp-chat-focus: #a9c3e2;
|
|
95
|
+
--bp-chat-user: #dfe7f2;
|
|
96
|
+
--bp-chat-on-user: #1e2635;
|
|
97
|
+
--bp-chat-danger: #f3b0a6;
|
|
98
|
+
--bp-chat-danger-bg: #3a2622;
|
|
99
|
+
--bp-chat-warning: #e6c188;
|
|
100
|
+
--bp-chat-warning-bg: #352c1e;
|
|
101
|
+
--bp-chat-shadow: 0 1px 2px #00000038, 0 10px 28px -14px #0000005c;
|
|
102
|
+
--bp-chat-shadow-float: 0 2px 8px -2px #00000047, 0 20px 44px -22px #00000073;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* ---------------------------------------------------------------------------
|
|
106
|
+
* Product islands: the controls this plugin adds to the native surface.
|
|
107
|
+
* ------------------------------------------------------------------------- */
|
|
108
|
+
|
|
109
|
+
/* OpenMausBot's standard/wide/full measures, applied through the pinned
|
|
110
|
+
conversation's existing width token. No composer state or DOM mutation.
|
|
111
|
+
The measure is a length, not a colour, so it lives in the --bt- sizing
|
|
112
|
+
namespace: the --bp-chat- namespace is the palette and every token in it is
|
|
113
|
+
read back by the contrast contract as a plain colour. */
|
|
114
|
+
html body[data-bot-product-ui] { --bt-column-width: min(60rem, 100%); }
|
|
115
|
+
html body[data-bot-product-ui][data-bp-chat-width=wide] { --bt-column-width: min(80rem, 100%); --bt-msg-w: .92; }
|
|
116
|
+
html body[data-bot-product-ui][data-bp-chat-width=full] { --bt-column-width: 100%; --bt-msg-w: .96; }
|
|
117
|
+
html body[data-bot-product-ui] [class*="_body"]:has(> [class*="_scrollBody"]) { --dsh-chat-content-width: var(--bt-column-width); }
|
|
118
|
+
/* A plain user bubble repaints the vendor's own --bt-user pair, so the shell's
|
|
119
|
+
bubble and the product's bubble change together. The neutral pair is the ink
|
|
120
|
+
on the inset surface the palette already measures, so it names no new colour
|
|
121
|
+
and the palette tokens keep the plain values the contrast contract reads. */
|
|
122
|
+
html body[data-bot-product-ui][data-bp-user-bubbles=neutral] { --bt-user: var(--bp-chat-inset); --bt-user-ink: var(--bp-chat-ink); }
|
|
123
|
+
|
|
124
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) {
|
|
125
|
+
color: var(--bp-chat-ink, var(--bp-ink));
|
|
126
|
+
font-family: var(--bp-font, system-ui, sans-serif);
|
|
127
|
+
font-size: 12px;
|
|
128
|
+
line-height: 1.5;
|
|
129
|
+
/* The mac header strip is the window's drag area; nothing here may drag it. */
|
|
130
|
+
-webkit-app-region: no-drag;
|
|
131
|
+
--bp-ink: var(--bp-chat-ink);
|
|
132
|
+
--bp-muted: var(--bp-chat-muted);
|
|
133
|
+
--bp-surface: var(--bp-chat-surface);
|
|
134
|
+
--bp-subtle: var(--bp-chat-inset);
|
|
135
|
+
--bp-hover: var(--bp-chat-hover);
|
|
136
|
+
--bp-border: var(--bp-chat-line);
|
|
137
|
+
--bp-solid: var(--bp-chat-accent);
|
|
138
|
+
--bp-focus: var(--bp-chat-focus);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) * { box-sizing: border-box; }
|
|
142
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) :is(button, summary) { font-family: inherit; touch-action: manipulation; -webkit-app-region: no-drag; }
|
|
143
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) :is(button, summary):focus-visible { outline: 2px solid var(--bp-chat-focus); outline-offset: 2px; border-radius: 9px; }
|
|
144
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) button:disabled { opacity: .55; cursor: wait; }
|
|
145
|
+
/* A long Bot name or a wrapped error must never push the column sideways. */
|
|
146
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) :is(span, strong, div, p) { min-width: 0; overflow-wrap: anywhere; }
|
|
147
|
+
body[data-bot-product-ui] :is(.bp-contact-resources, .bp-conversation-overflow) { position: relative; flex: none; }
|
|
148
|
+
body[data-bot-product-ui] :is(.bp-contact-resources, .bp-conversation-overflow) > summary { list-style: none; cursor: pointer; }
|
|
149
|
+
body[data-bot-product-ui] :is(.bp-contact-resources, .bp-conversation-overflow) > summary::-webkit-details-marker { display: none; }
|
|
150
|
+
|
|
151
|
+
/* Contact navigation, under the native list. Destinations only change focus. */
|
|
152
|
+
body[data-bot-product-ui] .bp-contact-nav { position: relative; flex: none; margin-top: 10px; padding: 11px 0 2px; border-top: 1px solid var(--bp-chat-line); }
|
|
153
|
+
body[data-bot-product-ui] .bt-side > .bp-contact-nav { order: 3; }
|
|
154
|
+
body[data-bot-product-ui] .bt-side > .bt-leftcol-foot { order: 4; }
|
|
155
|
+
body[data-bot-product-ui] .bp-contact-nav-row { display: flex; align-items: center; gap: 2px; }
|
|
156
|
+
body[data-bot-product-ui] .bp-contact-nav-row > .bp-appearance { margin-left: auto; }
|
|
157
|
+
body[data-bot-product-ui] .bp-contact-nav-button,
|
|
158
|
+
body[data-bot-product-ui] .bp-contact-resources > summary { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-width: 0; min-height: 35px; padding: 7px 6px; border: 0; border-radius: 10px; background: transparent; color: var(--bp-chat-muted); cursor: pointer; font-size: 11px; white-space: nowrap; }
|
|
159
|
+
body[data-bot-product-ui] .bp-contact-nav-row svg { flex: none; }
|
|
160
|
+
body[data-bot-product-ui] .bp-contact-nav-label { overflow: hidden; text-overflow: ellipsis; }
|
|
161
|
+
body[data-bot-product-ui] :is(.bp-contact-nav-button:hover, .bp-contact-resources > summary:hover, .bp-contact-resources[open] > summary) { color: var(--bp-chat-ink); background: var(--bp-chat-hover); }
|
|
162
|
+
body[data-bot-product-ui] :is(.bp-contact-nav-button[aria-current=page], .bp-contact-resources > summary[data-active]) { color: var(--bp-chat-accent); background: var(--bt-active); font-weight: 550; }
|
|
163
|
+
/* The attention count is a real number on a real surface, so it stays AA. */
|
|
164
|
+
body[data-bot-product-ui] .bp-contact-attention { display: inline-flex; align-items: center; justify-content: center; min-width: 17px; padding: 0 5px; border-radius: 6px; font-size: 10px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--bp-chat-danger); background: var(--bp-chat-danger-bg); }
|
|
165
|
+
body[data-bot-product-ui] .bp-contact-nav .bp-appearance > summary { width: 34px; height: 35px; border-radius: 10px; }
|
|
166
|
+
|
|
167
|
+
/* Menus: the resource list, the conversation overflow and the appearance panel. */
|
|
168
|
+
body[data-bot-product-ui] .bp-contact-resources-menu,
|
|
169
|
+
body[data-bot-product-ui] .bp-conversation-menu { position: absolute; z-index: 65; display: flex; flex-direction: column; gap: 2px; width: 208px; max-height: min(380px, 60dvh); overflow: auto; overscroll-behavior: contain; padding: 6px; border: 1px solid var(--bp-chat-line); border-radius: 13px; background: var(--bp-chat-surface); color: var(--bp-chat-ink); box-shadow: var(--bp-chat-shadow-float); }
|
|
170
|
+
body[data-bot-product-ui] .bp-contact-resources-menu { left: 0; bottom: calc(100% + 9px); }
|
|
171
|
+
body[data-bot-product-ui] :is(.bp-contact-resources-menu, .bp-conversation-menu) > button { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 36px; padding: 8px 10px; border: 0; border-radius: 9px; color: inherit; background: transparent; cursor: pointer; font-size: 12px; text-align: left; }
|
|
172
|
+
body[data-bot-product-ui] :is(.bp-contact-resources-menu, .bp-conversation-menu) > button:hover { background: var(--bp-chat-hover); }
|
|
173
|
+
body[data-bot-product-ui] :is(.bp-contact-resources-menu, .bp-conversation-menu) > button[aria-current=page] { color: var(--bp-chat-accent); background: var(--bt-active); font-weight: 550; }
|
|
174
|
+
body[data-bot-product-ui] :is(.bp-contact-resources-menu, .bp-conversation-menu) > button > :last-child { margin-left: auto; color: var(--bp-chat-muted); }
|
|
175
|
+
body[data-bot-product-ui] .bp-contact-resources-menu > .bp-contact-advanced { margin-top: 4px; border-top: 1px solid var(--bp-chat-line); border-radius: 0 0 9px 9px; padding-top: 11px; color: var(--bp-chat-muted); }
|
|
176
|
+
body[data-bot-product-ui] .bp-contact-nav .bp-appearance-menu { top: auto; right: 0; bottom: calc(100% + 9px); width: min(265px, calc(100vw - 24px)); max-height: 65dvh; overflow: auto; padding: 18px; box-shadow: var(--bp-chat-shadow-float); }
|
|
177
|
+
body[data-bot-product-ui] .bp-contact-nav .bp-segmented > button { flex: 1; min-width: 0; min-height: 30px; padding: 5px 7px; border: 1px solid transparent; border-radius: 7px; color: var(--bp-chat-muted); background: transparent; font-size: 11px; cursor: pointer; }
|
|
178
|
+
body[data-bot-product-ui] .bp-contact-nav .bp-segmented > button[aria-pressed=true] { border-color: var(--bp-chat-line); color: var(--bp-chat-ink); background: var(--bp-chat-surface); }
|
|
179
|
+
|
|
180
|
+
/* Rail-width column: the nav collapses to icons, its menus open sideways. */
|
|
181
|
+
body[data-bot-product-ui] .bp-contact-nav-compact { width: 100%; margin-top: 6px; padding-top: 8px; }
|
|
182
|
+
body[data-bot-product-ui] .bp-contact-nav-compact .bp-contact-nav-row { flex-direction: column; gap: 4px; }
|
|
183
|
+
body[data-bot-product-ui] .bp-contact-nav-compact .bp-contact-nav-row > .bp-appearance { margin-left: 0; }
|
|
184
|
+
body[data-bot-product-ui] .bp-contact-nav-compact .bp-contact-nav-label { display: none; }
|
|
185
|
+
body[data-bot-product-ui] .bp-contact-nav-compact :is(.bp-contact-nav-button, .bp-contact-resources > summary) { position: relative; width: 38px; min-height: 36px; padding: 7px; }
|
|
186
|
+
body[data-bot-product-ui] .bp-contact-nav-compact .bp-contact-attention { position: absolute; right: -3px; top: -1px; min-width: 16px; }
|
|
187
|
+
body[data-bot-product-ui] .bp-contact-nav-compact :is(.bp-contact-resources-menu, .bp-appearance-menu) { left: calc(100% + 12px); right: auto; bottom: 0; }
|
|
188
|
+
|
|
189
|
+
/* The list header: who these contacts are, plus the native search and new chat. */
|
|
190
|
+
body[data-bot-product-ui] .bp-contact-toolbar { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: none; min-height: 44px; padding: 3px 2px 9px; }
|
|
191
|
+
body[data-bot-product-ui] .bp-contact-toolbar > strong { font-size: 14px; font-weight: 620; letter-spacing: -.02em; }
|
|
192
|
+
body[data-bot-product-ui] .bp-contact-toolbar-actions { display: flex; gap: 3px; }
|
|
193
|
+
body[data-bot-product-ui] .bp-contact-toolbar-actions > button { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 10px; color: var(--bp-chat-muted); background: transparent; cursor: pointer; }
|
|
194
|
+
body[data-bot-product-ui] .bp-contact-toolbar-actions > button:hover { background: var(--bp-chat-hover); color: var(--bp-chat-ink); }
|
|
195
|
+
body[data-bot-product-ui] .bp-contact-toolbar-compact { justify-content: center; }
|
|
196
|
+
body[data-bot-product-ui] .bp-contact-toolbar-compact .bp-contact-toolbar-actions { flex-direction: column; }
|
|
197
|
+
|
|
198
|
+
/* An action failure is stated once, in place, and dismissed by hand. */
|
|
199
|
+
body[data-bot-product-ui] .bp-chat-action-error { position: absolute; z-index: 70; display: flex; align-items: flex-start; gap: 12px; width: max-content; max-width: min(340px, calc(100vw - 24px)); padding: 10px 11px; border: 1px solid color-mix(in srgb, var(--bp-chat-danger) 30%, var(--bp-chat-line)); border-radius: 12px; color: var(--bp-chat-danger); background: var(--bp-chat-surface); box-shadow: var(--bp-chat-shadow-float); text-align: left; font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
|
|
200
|
+
body[data-bot-product-ui] .bp-chat-action-error > span { flex: 1; min-width: 0; }
|
|
201
|
+
body[data-bot-product-ui] .bp-chat-action-error > button { display: grid; place-items: center; flex: none; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 7px; background: transparent; color: inherit; cursor: pointer; }
|
|
202
|
+
body[data-bot-product-ui] .bp-chat-action-error > button:hover { background: var(--bp-chat-inset); }
|
|
203
|
+
body[data-bot-product-ui] .bp-conversation-tools > .bp-chat-action-error { top: calc(100% + 12px); right: 0; }
|
|
204
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar) > .bp-chat-action-error { bottom: calc(100% + 8px); left: 0; }
|
|
205
|
+
body[data-bot-product-ui] .bp-contact-nav-compact > .bp-chat-action-error { left: calc(100% + 8px); bottom: 0; }
|
|
206
|
+
|
|
207
|
+
/* ---------------------------------------------------------------------------
|
|
208
|
+
* Contact list. The native rows, tiles and marks keep their DOM; only the
|
|
209
|
+
* spacing, the type ladder and the active treatment are the design's.
|
|
210
|
+
* ------------------------------------------------------------------------- */
|
|
211
|
+
|
|
212
|
+
body[data-bot-product-ui] .bt-side { background: var(--bp-chat-sidebar); }
|
|
213
|
+
body[data-bot-product-ui] .bt-side:not(.bt-rail) { padding-right: 0; }
|
|
214
|
+
body[data-bot-product-ui] .bt-side:not(.bt-rail) > .bt-list { gap: 4px; margin-right: -4px; padding-right: 4px; }
|
|
215
|
+
body[data-bot-product-ui] .bt-side-top { gap: 4px; min-height: 43px; padding: 4px 0 12px; }
|
|
216
|
+
body[data-bot-product-ui] .bt-brand { font-size: 14px; font-weight: 600; color: var(--bp-chat-accent); }
|
|
217
|
+
body[data-bot-product-ui] .bt-side:not(.bt-rail) .bt-row { position: relative; gap: 11px; min-height: 56px; padding: 9px 10px; border-radius: 12px; overflow: hidden; }
|
|
218
|
+
body[data-bot-product-ui] .bt-side:not(.bt-rail) .bt-row:hover { background: var(--bp-chat-hover); }
|
|
219
|
+
body[data-bot-product-ui] .bt-side:not(.bt-rail) .bt-row[aria-current=page] { background: var(--bp-chat-surface); box-shadow: 0 1px 4px #252a3308, inset 0 0 0 1px var(--bp-chat-line); }
|
|
220
|
+
/* The current contact carries an accent edge, the way a chat client marks the
|
|
221
|
+
open thread, so the list reads at a glance without relying on weight alone. */
|
|
222
|
+
body[data-bot-product-ui] .bt-side:not(.bt-rail) .bt-row[aria-current=page]::before { content: ""; position: absolute; left: 0; top: 50%; translate: 0 -50%; width: 3px; height: 58%; border-radius: 0 3px 3px 0; background: var(--bp-chat-accent); }
|
|
223
|
+
body[data-bot-product-ui] .bt-row-body { min-width: 0; }
|
|
224
|
+
body[data-bot-product-ui] .bt-row-name { gap: 6px; font-size: 13px; line-height: 19px; font-weight: 550; }
|
|
225
|
+
body[data-bot-product-ui] .bt-row-title { min-width: 0; }
|
|
226
|
+
body[data-bot-product-ui] .bt-row-preview { margin-top: 2px; font-size: 12px; line-height: 17px; color: var(--bp-chat-muted); }
|
|
227
|
+
body[data-bot-product-ui] .bt-row[aria-current=page] .bt-row-preview { color: var(--bp-chat-ink); }
|
|
228
|
+
body[data-bot-product-ui] .bt-unread { width: 8px; height: 8px; border-radius: 50%; background: var(--bp-chat-accent); }
|
|
229
|
+
body[data-bot-product-ui] .bt-unread-wait { background: var(--bp-chat-warning); }
|
|
230
|
+
body[data-bot-product-ui] .bt-tag { max-width: 96px; padding: 1px 6px; border-radius: 6px; background: var(--bp-chat-inset); color: var(--bp-chat-muted); font-size: 11px; }
|
|
231
|
+
body[data-bot-product-ui] .bt-leftcol-foot { padding-top: 8px; }
|
|
232
|
+
body[data-bot-product-ui] .bt-urow { margin-block: 8px; color: var(--bp-chat-ink); }
|
|
233
|
+
/* The Main Bot's tile is a contact card, not a button floating in space. */
|
|
234
|
+
body[data-bot-product-ui] .bt-tile-wrap { padding: 6px 0 10px; }
|
|
235
|
+
body[data-bot-product-ui] .bt-tile { gap: 11px; width: 100%; padding: 10px; border-radius: 12px; background: var(--bp-chat-inset); text-align: left; }
|
|
236
|
+
body[data-bot-product-ui] .bt-tile[aria-current=page] { background: var(--bp-chat-surface); box-shadow: inset 0 0 0 1px var(--bp-chat-line); }
|
|
237
|
+
body[data-bot-product-ui] .bt-tile-name { max-width: none; font-size: 13px; line-height: 19px; font-weight: 550; }
|
|
238
|
+
body[data-bot-product-ui] .bt-tile > .bt-chip { max-width: 100%; padding: 0; border: 0; background: transparent; font-size: 11px; color: var(--bp-chat-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
239
|
+
body[data-bot-product-ui] .bt-chip { border-radius: 6px; background: var(--bp-chat-inset); color: var(--bp-chat-muted); }
|
|
240
|
+
/* A read-only roster notice and the "return" row are part of the list, not modals. */
|
|
241
|
+
body[data-bot-product-ui] .bt-side .bt-read-only { margin: 4px 2px 8px; padding: 9px 11px; border-radius: 10px; background: var(--bp-chat-inset); color: var(--bp-chat-muted); font-size: 11px; line-height: 1.6; }
|
|
242
|
+
body[data-bot-product-ui] .bt-return .bt-row { min-height: 44px; border-radius: 10px; }
|
|
243
|
+
body[data-bot-product-ui] .bt-return .bt-mark { color: var(--bp-chat-muted); }
|
|
244
|
+
|
|
245
|
+
/* ---------------------------------------------------------------------------
|
|
246
|
+
* Conversation header. DS Bot floats a pill over the transcript; the product's
|
|
247
|
+
* tools ride the same band. The vendor pins this header's padding, background
|
|
248
|
+
* and border with !important, so the same properties are restated here with a
|
|
249
|
+
* selector that outranks it.
|
|
250
|
+
* ------------------------------------------------------------------------- */
|
|
251
|
+
|
|
252
|
+
body[data-bot-product-ui] header[class*="_header"]:has(.bp-conversation-tools) { padding: 10px 16px 10px 48px !important; background: var(--bp-chat-canvas) !important; border-bottom: 1px solid var(--bp-chat-line) !important; box-shadow: none !important; container-name: bp-chat-header; container-type: inline-size; }
|
|
253
|
+
body[data-bot-product-ui] header[class*="_header"]:has(.bp-conversation-tools)::before { background: none; }
|
|
254
|
+
body[data-bot-product-ui] .bt-head:has(> .bp-conversation-tools) { min-width: 0; justify-content: space-between; gap: 12px; }
|
|
255
|
+
body[data-bot-product-ui] .bt-head:has(> .bp-conversation-tools) > .bt-pill { flex: 0 1 auto; min-width: 0; max-width: min(45%, 400px); border: 1px solid var(--bp-chat-line); background: var(--bp-chat-surface); box-shadow: var(--bp-chat-shadow); }
|
|
256
|
+
body[data-bot-product-ui] .bt-head:has(> .bp-conversation-tools) > .bt-island { flex: 0 1 auto; min-width: 0; max-width: calc(100% - 140px); background: var(--bp-chat-surface); border-color: var(--bp-chat-line); box-shadow: var(--bp-chat-shadow-float); }
|
|
257
|
+
body[data-bot-product-ui] .bt-pill { font-size: 13px; }
|
|
258
|
+
body[data-bot-product-ui] .bt-pill-name { font-weight: 550; }
|
|
259
|
+
body[data-bot-product-ui] .bt-pill-mem-in { color: var(--bp-chat-muted); }
|
|
260
|
+
body[data-bot-product-ui] .bt-swap { color: var(--bp-chat-muted); }
|
|
261
|
+
body[data-bot-product-ui] .bp-conversation-tools { position: relative; display: flex; align-items: center; justify-content: flex-end; gap: 4px; flex: 0 0 auto; min-width: 0; margin-left: auto; pointer-events: auto; }
|
|
262
|
+
body[data-bot-product-ui] .bp-conversation-tools > button,
|
|
263
|
+
body[data-bot-product-ui] .bp-conversation-shortcuts > button,
|
|
264
|
+
body[data-bot-product-ui] .bp-conversation-overflow > summary { display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex: none; width: 32px; height: 32px; min-width: 32px; padding: 0; border: 1px solid transparent; border-radius: 10px; color: var(--bp-chat-muted); background: transparent; cursor: pointer; }
|
|
265
|
+
/* Model and members read as chips beside the icons, so the header states what
|
|
266
|
+
the conversation is without opening anything. */
|
|
267
|
+
body[data-bot-product-ui] .bp-conversation-tools > .bp-conversation-model,
|
|
268
|
+
body[data-bot-product-ui] .bp-conversation-tools > .bp-conversation-members { width: auto; max-width: 180px; padding: 0 10px; border-color: var(--bp-chat-line); border-radius: 999px; background: var(--bp-chat-surface); font-size: 11px; white-space: nowrap; }
|
|
269
|
+
body[data-bot-product-ui] .bp-conversation-tools > .bp-conversation-model:hover,
|
|
270
|
+
body[data-bot-product-ui] .bp-conversation-tools > .bp-conversation-members:hover { color: var(--bp-chat-ink); background: var(--bp-chat-hover); }
|
|
271
|
+
body[data-bot-product-ui] .bp-conversation-model-name { overflow: hidden; text-overflow: ellipsis; }
|
|
272
|
+
body[data-bot-product-ui] .bp-conversation-model-different { flex: none; width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .7; }
|
|
273
|
+
body[data-bot-product-ui] .bp-conversation-model > svg,
|
|
274
|
+
body[data-bot-product-ui] .bp-conversation-members > svg { flex: none; }
|
|
275
|
+
body[data-bot-product-ui] .bp-conversation-tools > button:hover,
|
|
276
|
+
body[data-bot-product-ui] .bp-conversation-shortcuts > button:hover,
|
|
277
|
+
body[data-bot-product-ui] .bp-conversation-overflow > summary:hover,
|
|
278
|
+
body[data-bot-product-ui] .bp-conversation-overflow[open] > summary { color: var(--bp-chat-ink); background: var(--bp-chat-inset); }
|
|
279
|
+
body[data-bot-product-ui] .bp-conversation-shortcuts { display: flex; gap: 2px; }
|
|
280
|
+
/* "Working" is one small dot with a label, never a banner over the transcript. */
|
|
281
|
+
body[data-bot-product-ui] .bp-conversation-live { display: inline-flex; align-items: center; justify-content: center; width: 10px; height: 22px; margin: 0 3px 0 -1px; }
|
|
282
|
+
body[data-bot-product-ui] .bp-conversation-live > span { width: 6px; height: 6px; border-radius: 50%; background: var(--bp-chat-accent); animation: bp-chat-live 1.6s ease-in-out infinite; }
|
|
283
|
+
@keyframes bp-chat-live { 50% { opacity: .35; } }
|
|
284
|
+
body[data-bot-product-ui] .bp-conversation-overflow { display: none; }
|
|
285
|
+
body[data-bot-product-ui] .bp-conversation-menu { top: calc(100% + 10px); right: 0; width: 178px; }
|
|
286
|
+
|
|
287
|
+
/* ---------------------------------------------------------------------------
|
|
288
|
+
* Transcript. Bot replies sit on the surface with a hairline; the user's own
|
|
289
|
+
* messages are the filled bubble; everything between them is quiet meta.
|
|
290
|
+
* ------------------------------------------------------------------------- */
|
|
291
|
+
|
|
292
|
+
body[data-bot-product-ui] .bt-bubble { color: var(--bp-chat-ink); }
|
|
293
|
+
body[data-bot-product-ui]:not([data-bt-layout=flat]) .bt-bubble { padding: 10px 14px; border: 1px solid var(--bp-chat-line); border-radius: 16px; background: var(--bp-chat-surface); line-height: 1.65; }
|
|
294
|
+
body[data-bot-product-ui]:not([data-bt-layout=flat]) .bt-bubble:hover { border-color: color-mix(in srgb, var(--bp-chat-muted) 40%, var(--bp-chat-line)); }
|
|
295
|
+
body[data-bot-product-ui] .bt-bubble p + p { margin-top: 6px; }
|
|
296
|
+
body[data-bot-product-ui] .bt-bubble :is(ul, ol) { margin: 4px 0; padding-left: 20px; }
|
|
297
|
+
/* Long code and long paths scroll inside the bubble; they never widen the page. */
|
|
298
|
+
body[data-bot-product-ui] .bt-bubble :is(pre, .bt-fold-pre) { max-width: 100%; margin: 8px 0; padding: 10px 12px; border-radius: 10px; background: var(--bp-chat-inset); overflow-x: auto; overscroll-behavior: contain; }
|
|
299
|
+
body[data-bot-product-ui] .bt-bubble pre { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.6; }
|
|
300
|
+
body[data-bot-product-ui] .bt-bubble pre code { padding: 0; background: none; font-size: inherit; white-space: pre; }
|
|
301
|
+
body[data-bot-product-ui] .bt-bubble :not(pre) > code { padding: 1px 5px; border-radius: 5px; background: var(--bp-chat-inset); font-size: .92em; overflow-wrap: anywhere; }
|
|
302
|
+
body[data-bot-product-ui] .bt-bubble :is(img, video) { max-width: 100%; height: auto; border-radius: 10px; }
|
|
303
|
+
body[data-bot-product-ui] .bt-bubble table { display: block; max-width: 100%; overflow-x: auto; }
|
|
304
|
+
/* The user's own words: one filled bubble per turn, in both renderers DS Bot
|
|
305
|
+
uses (.bt-urow for earlier parts and replies, .bt-umsg for the live column).
|
|
306
|
+
The fill and its ink come from the vendor's own --bt-user pair, so the plain
|
|
307
|
+
(neutral) preference repaints this bubble and the shell's bubble together. */
|
|
308
|
+
body[data-bot-product-ui] .bt-ububble,
|
|
309
|
+
body[data-bot-product-ui] .bt-ubody { padding: 9px 14px; border-radius: 16px 16px 5px 16px; background: var(--bt-user); color: var(--bt-user-ink); line-height: calc(var(--dsh-content-font-size, 14px) + 9px); overflow-wrap: anywhere; }
|
|
310
|
+
body[data-bot-product-ui] .bt-ubody { border: 0; }
|
|
311
|
+
body[data-bot-product-ui] .bt-ubody :not(pre) > code { background: color-mix(in srgb, currentColor 14%, transparent); }
|
|
312
|
+
body[data-bot-product-ui] .bt-ubody pre { background: color-mix(in srgb, currentColor 10%, transparent); }
|
|
313
|
+
body[data-bot-product-ui] .bt-ububble a { color: inherit; }
|
|
314
|
+
/* The shell's own user bubble (older hosts, question replies, command input)
|
|
315
|
+
pins these three properties with !important; the colours come from the tokens
|
|
316
|
+
above, the geometry is restated to match the renderers beside it. */
|
|
317
|
+
body[data-bot-product-ui] :is([class*="_userRow"], [data-chat-flow-kind=question-reply], [data-chat-flow-kind=command-input]) [class*="_bubble"] { border-radius: 16px !important; padding: 9px 14px !important; line-height: calc(var(--dsh-content-font-size, 14px) + 9px) !important; }
|
|
318
|
+
body[data-bot-product-ui] .bt-utime { font-size: 11px; color: var(--bp-chat-muted); font-variant-numeric: tabular-nums; }
|
|
319
|
+
body[data-bot-product-ui] .bt-uimages { font-size: 11px; opacity: .75; }
|
|
320
|
+
body[data-bot-product-ui] .bt-ufile { border-radius: 14px; border-color: var(--bp-chat-line); background: var(--bp-chat-surface); }
|
|
321
|
+
body[data-bot-product-ui] .bt-ufile-name { color: var(--bp-chat-ink); }
|
|
322
|
+
body[data-bot-product-ui] .bt-urefs { font-size: 12px; color: var(--bp-chat-muted); }
|
|
323
|
+
/* A group chat names its speaker once per run, quietly, above the run. */
|
|
324
|
+
body[data-bot-product-ui] .bt-group-name { margin-left: 42px; font-size: 12.5px; line-height: 20px; font-weight: 600; }
|
|
325
|
+
body[data-bot-product-ui] .bt-group-name:has(>.bt-lead) { margin: 0 0 3px; font-size: 13px; line-height: 22px; }
|
|
326
|
+
body[data-bot-product-ui] .bt-group-time,
|
|
327
|
+
body[data-bot-product-ui] .bt-group-took { margin-left: 6px; font-size: 11px; color: var(--bp-chat-muted); }
|
|
328
|
+
body[data-bot-product-ui] .bt-group-role { margin-left: 6px; font-size: 10px; font-weight: 500; color: var(--bp-chat-muted); }
|
|
329
|
+
/* Separators: a day, a part boundary, an unread line. Rules, not boxes. */
|
|
330
|
+
body[data-bot-product-ui] .bt-time-sep { height: 28px; margin: 14px 0 8px; font-size: 11.5px; color: var(--bp-chat-muted); }
|
|
331
|
+
body[data-bot-product-ui] .bt-part-line { gap: 10px; margin: 12px 0 8px; font-size: 11px; color: var(--bp-chat-muted); }
|
|
332
|
+
body[data-bot-product-ui] .bt-part-line::before,
|
|
333
|
+
body[data-bot-product-ui] .bt-part-line::after { height: 1px; background: var(--bp-chat-line); }
|
|
334
|
+
body[data-bot-product-ui] .bt-new-sep { margin: 14px 0 8px; font-size: 10.5px; font-weight: 600; letter-spacing: .06em; color: var(--bp-chat-accent); }
|
|
335
|
+
body[data-bot-product-ui] .bt-new-sep::before,
|
|
336
|
+
body[data-bot-product-ui] .bt-new-sep::after { height: 1px; background: color-mix(in srgb, var(--bp-chat-accent) 28%, transparent); }
|
|
337
|
+
/* Tool calls and lifecycle notes: one quiet centred line each. */
|
|
338
|
+
body[data-bot-product-ui] .bt-event { gap: 2px; min-height: 24px; margin: 3px 0; font-size: 12px; color: var(--bp-chat-muted); }
|
|
339
|
+
body[data-bot-product-ui] .bt-event button:not(.bt-soft) { height: 24px; padding: 4px 7px 4px 5px; border-radius: 999px; }
|
|
340
|
+
body[data-bot-product-ui] .bt-event .bt-soft { margin-left: 6px; }
|
|
341
|
+
body[data-bot-product-ui] .bt-event-error { color: var(--bp-chat-danger); }
|
|
342
|
+
body[data-bot-product-ui] .bt-activity { gap: 10px; margin: 8px 0 4px 2px; font-size: 13px; color: var(--bp-chat-muted); }
|
|
343
|
+
/* Reasoning folds shut to one line and opens into a ruled inset. */
|
|
344
|
+
body[data-bot-product-ui] .bt-think { font-size: 12.5px; color: var(--bp-chat-muted); }
|
|
345
|
+
body[data-bot-product-ui] .bt-think summary { gap: 6px; }
|
|
346
|
+
body[data-bot-product-ui] .bt-think summary:hover { color: var(--bp-chat-ink); }
|
|
347
|
+
body[data-bot-product-ui] .bt-think-text { margin-top: 6px; padding: 8px 11px; border-left: 2px solid var(--bp-chat-line-strong); border-radius: 0 8px 8px 0; background: var(--bp-chat-inset); font-size: 12.5px; line-height: 1.6; }
|
|
348
|
+
/* The activity row: who is working, and for how long. */
|
|
349
|
+
body[data-bot-product-ui] .bt-typing { height: 36px; gap: 12px; padding-inline-start: 8px; }
|
|
350
|
+
body[data-bot-product-ui] .bt-typing-label > .bt-shimmer { font-size: 13.5px; }
|
|
351
|
+
body[data-bot-product-ui] .bt-typing-time { color: var(--bp-chat-muted); }
|
|
352
|
+
/* Message tools stay reachable by keyboard and touch, not hover only. */
|
|
353
|
+
body[data-bot-product-ui] .bt-tool { width: 26px; height: 26px; border-radius: 8px; }
|
|
354
|
+
body[data-bot-product-ui] .bt-react { border: 0; background: none; cursor: pointer; }
|
|
355
|
+
/* A turn that failed states what happened and what to do next, in place. */
|
|
356
|
+
body[data-bot-product-ui] .bt-fail { border-radius: 14px; background: var(--bp-chat-surface); box-shadow: inset 0 0 0 1px var(--bp-chat-line); }
|
|
357
|
+
body[data-bot-product-ui] .bt-fail-dot { background: var(--bp-chat-danger); }
|
|
358
|
+
body[data-bot-product-ui] .bt-fail-error { color: var(--bp-chat-danger); }
|
|
359
|
+
|
|
360
|
+
/* ---------------------------------------------------------------------------
|
|
361
|
+
* Question and approval cards. These are the conversation's decisions, so they
|
|
362
|
+
* are the one surface allowed to look like a card — and nothing here hides a
|
|
363
|
+
* control or caps a height the answer needs.
|
|
364
|
+
* ------------------------------------------------------------------------- */
|
|
365
|
+
|
|
366
|
+
body[data-bot-product-ui] .bt-q { gap: 12px; padding: 14px 16px; border-radius: 16px; background: var(--bp-chat-surface); box-shadow: 0 1px 3px #252a330a, inset 0 0 0 1px var(--bp-chat-line); }
|
|
367
|
+
body[data-bot-product-ui] .bt-q-title { font-size: 14.5px; line-height: 21px; font-weight: 600; }
|
|
368
|
+
body[data-bot-product-ui] .bt-q-detail { font-size: 12.5px; line-height: 18px; color: var(--bp-chat-muted); }
|
|
369
|
+
body[data-bot-product-ui] .bt-q-opt { gap: 14px; min-height: 40px; padding: 9px 10px; border-radius: 11px; }
|
|
370
|
+
body[data-bot-product-ui] .bt-q-label { font-size: 13.5px; line-height: 19px; }
|
|
371
|
+
body[data-bot-product-ui] .bt-q-desc { font-size: 12px; line-height: 17px; color: var(--bp-chat-muted); }
|
|
372
|
+
body[data-bot-product-ui] .bt-q-submit { height: 34px; padding: 0 16px; border-radius: 999px; background: var(--bp-chat-accent); color: var(--bp-chat-accent-ink); font-size: 13.5px; font-weight: 550; }
|
|
373
|
+
body[data-bot-product-ui] .bt-q-submit:hover:not(:disabled) { opacity: .9; }
|
|
374
|
+
body[data-bot-product-ui] .bt-q-btn { height: 34px; padding: 0 14px; border-radius: 999px; background: var(--bp-chat-inset); color: var(--bp-chat-ink); font-size: 13px; }
|
|
375
|
+
body[data-bot-product-ui] .bt-q-field { min-height: 34px; border-radius: 9px; border-color: var(--bp-chat-line-strong); }
|
|
376
|
+
body[data-bot-product-ui] .bt-q-badge { border-radius: 999px; color: var(--bp-chat-muted); }
|
|
377
|
+
|
|
378
|
+
/* ---------------------------------------------------------------------------
|
|
379
|
+
* Composer. DS Bot pins the card's surface, radius and shadow with !important
|
|
380
|
+
* and owns the whole layout (tools, input, trailing controls, the send/stop
|
|
381
|
+
* swap). This sheet restates the surface in the chat palette and leaves every
|
|
382
|
+
* control where the native component put it.
|
|
383
|
+
* ------------------------------------------------------------------------- */
|
|
384
|
+
|
|
385
|
+
body[data-bot-product-ui] [data-composer-card] { background: var(--bp-chat-surface) !important; border: 1px solid var(--bp-chat-line) !important; border-radius: 20px !important; box-shadow: var(--bp-chat-shadow) !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
|
|
386
|
+
body[data-bot-product-ui] [data-composer-card]:hover { border-color: color-mix(in srgb, var(--bp-chat-muted) 45%, var(--bp-chat-line)) !important; }
|
|
387
|
+
body[data-bot-product-ui] [data-composer-card]:focus-within { border-color: var(--bp-chat-accent) !important; box-shadow: var(--bp-chat-shadow), 0 0 0 3px color-mix(in srgb, var(--bp-chat-accent) 18%, transparent) !important; }
|
|
388
|
+
/* Every control in the card keeps a visible focus ring; the native ones set
|
|
389
|
+
their own colours, the ones DS Bot adds get the chat palette. */
|
|
390
|
+
body[data-bot-product-ui] [data-composer-card] :is(button, [role=button], [contenteditable=true]):focus-visible { outline: 2px solid var(--bp-chat-focus); outline-offset: 2px; }
|
|
391
|
+
body[data-bot-product-ui] [data-composer-card] :is(.bt-mic, .bt-voice) { width: 30px; height: 30px; color: var(--bp-chat-muted); }
|
|
392
|
+
body[data-bot-product-ui] [data-composer-card] :is(.bt-mic, .bt-voice):hover { color: var(--bp-chat-ink); background: var(--bp-chat-hover); }
|
|
393
|
+
body[data-bot-product-ui] [data-composer-card] .bt-voice { background: var(--bp-chat-accent); color: var(--bp-chat-accent-ink); }
|
|
394
|
+
body[data-bot-product-ui] .bt-mic-note { border-radius: 9px; background: var(--bt-user); color: var(--bt-user-ink); }
|
|
395
|
+
/* The queued-message dock and the side-question card share the card language. */
|
|
396
|
+
body[data-bot-product-ui] .bt-btw { border-radius: 13px; border-color: var(--bp-chat-line); background: var(--bp-chat-surface); }
|
|
397
|
+
body[data-bot-product-ui] .bt-btw-q { font-size: 12.5px; }
|
|
398
|
+
body[data-bot-product-ui] .bt-btw-note { color: var(--bp-chat-muted); }
|
|
399
|
+
|
|
400
|
+
/* ---------------------------------------------------------------------------
|
|
401
|
+
* Responsive, density, touch and motion.
|
|
402
|
+
* ------------------------------------------------------------------------- */
|
|
403
|
+
|
|
404
|
+
/* The open column gives the tile its row shape; the rail keeps the stacked one. */
|
|
405
|
+
@container bot-sidebar (min-width: 180px) {
|
|
406
|
+
body[data-bot-product-ui] .bt-tile-wrap { padding: 4px 0 8px; }
|
|
407
|
+
body[data-bot-product-ui] .bt-tile { grid-template-columns: 36px minmax(0, 1fr); column-gap: 11px; row-gap: 2px; min-height: 60px; }
|
|
408
|
+
body[data-bot-product-ui] .bt-tile > .bt-mark { grid-row: 1 / span 2; }
|
|
409
|
+
body[data-bot-product-ui] .bt-tile-name { grid-column: 2; grid-row: 1; }
|
|
410
|
+
body[data-bot-product-ui] .bt-tile > .bt-chip { grid-column: 2; grid-row: 2; justify-self: start; }
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* The header sheds its shortcuts before the composer does: the overflow menu
|
|
414
|
+
carries the same commands, so nothing becomes unreachable. */
|
|
415
|
+
@container bp-chat-header (max-width: 640px) {
|
|
416
|
+
body[data-bot-product-ui] .bp-conversation-shortcuts { display: none; }
|
|
417
|
+
body[data-bot-product-ui] .bp-conversation-overflow { display: block; }
|
|
418
|
+
body[data-bot-product-ui] .bp-conversation-tools > .bp-conversation-model { max-width: 140px; }
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
@container bp-chat-header (max-width: 420px) {
|
|
422
|
+
body[data-bot-product-ui] .bp-conversation-tools { gap: 2px; }
|
|
423
|
+
body[data-bot-product-ui] .bp-conversation-model-name,
|
|
424
|
+
body[data-bot-product-ui] .bp-conversation-model > svg:last-child,
|
|
425
|
+
body[data-bot-product-ui] .bp-conversation-members > span { display: none; }
|
|
426
|
+
body[data-bot-product-ui] .bp-conversation-tools > :is(.bp-conversation-model, .bp-conversation-members) { width: 32px; padding: 0; }
|
|
427
|
+
body[data-bot-product-ui] .bt-head:has(> .bp-conversation-tools) { gap: 6px; }
|
|
428
|
+
body[data-bot-product-ui] .bt-head:has(> .bp-conversation-tools) > .bt-pill { max-width: calc(100% - 110px); }
|
|
429
|
+
body[data-bot-product-ui] .bt-head:has(> .bp-conversation-tools) > .bt-island { max-width: calc(100% - 80px); }
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/* A phone: the transcript and the composer take the whole width, the bubbles
|
|
433
|
+
keep their share of it, and the meta rows stay readable at 375px. */
|
|
434
|
+
@media (max-width: 640px) {
|
|
435
|
+
body[data-bot-product-ui] .bt-msg { max-width: 100%; }
|
|
436
|
+
body[data-bot-product-ui] .bt-msg-line > .bt-bubble { max-width: 100%; }
|
|
437
|
+
body[data-bot-product-ui] .bt-bubble,
|
|
438
|
+
body[data-bot-product-ui] .bt-ububble,
|
|
439
|
+
body[data-bot-product-ui] .bt-ubody { max-width: calc(100% - 24px); }
|
|
440
|
+
body[data-bot-product-ui] .bt-group-name { margin-left: 30px; }
|
|
441
|
+
body[data-bot-product-ui] .bt-astack[data-lead]>.bt-msg:not(:last-child)>.bt-msg-line { margin-left: 26px; }
|
|
442
|
+
body[data-bot-product-ui] .bp-chat-action-error { max-width: calc(100vw - 32px); }
|
|
443
|
+
body[data-bot-product-ui] .bt-q { padding: 13px 14px; }
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
body[data-bot-product-ui][data-bp-density=compact] .bt-side:not(.bt-rail) .bt-row { min-height: 46px; padding: 7px 9px; }
|
|
447
|
+
body[data-bot-product-ui][data-bp-density=compact] .bt-row-preview { font-size: 11.5px; }
|
|
448
|
+
body[data-bot-product-ui][data-bp-density=compact] .bt-side-top { min-height: 38px; padding-bottom: 8px; }
|
|
449
|
+
body[data-bot-product-ui][data-bp-density=compact] .bt-tile { min-height: 52px; padding: 8px; }
|
|
450
|
+
body[data-bot-product-ui][data-bp-density=compact] .bt-time-sep { height: 22px; margin: 10px 0 6px; }
|
|
451
|
+
body[data-bot-product-ui][data-bp-density=compact] .bp-contact-toolbar { min-height: 38px; }
|
|
452
|
+
|
|
453
|
+
/* Touch: every target reaches 40px, and hover-only reveals become permanent. */
|
|
454
|
+
@media (pointer: coarse) {
|
|
455
|
+
body[data-bot-product-ui] :is(.bp-contact-toolbar-actions > button, .bp-conversation-tools > button, .bp-conversation-shortcuts > button, .bp-conversation-overflow > summary) { min-width: 40px; width: 40px; height: 40px; }
|
|
456
|
+
body[data-bot-product-ui] :is(.bp-contact-nav-button, .bp-contact-resources > summary, .bp-contact-resources-menu > button, .bp-conversation-menu > button) { min-height: 44px; }
|
|
457
|
+
body[data-bot-product-ui] .bt-tool { width: 34px; height: 34px; border-radius: 10px; }
|
|
458
|
+
body[data-bot-product-ui] .bt-q-opt { min-height: 44px; }
|
|
459
|
+
body[data-bot-product-ui] .bt-event button:not(.bt-soft) { height: 32px; }
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* No hover means no hover reveals: the message tools and the card's own
|
|
463
|
+
controls are already always visible here, and nothing else depends on hover. */
|
|
464
|
+
@media (hover: none) {
|
|
465
|
+
body[data-bot-product-ui] .bt-row:hover { background: transparent; }
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
@media (prefers-reduced-motion: reduce) {
|
|
469
|
+
body[data-bot-product-ui] :is(.bp-contact-nav, .bp-contact-toolbar, .bp-conversation-tools) * { transition: none; animation: none; }
|
|
470
|
+
body[data-bot-product-ui] .bp-conversation-live > span { animation: none; }
|
|
471
|
+
body[data-bot-product-ui] .bt-bubble,
|
|
472
|
+
body[data-bot-product-ui] .bt-ububble,
|
|
473
|
+
body[data-bot-product-ui] .bt-ubody { transition: none; }
|
|
474
|
+
}
|
|
475
|
+
html body[data-bot-product-ui] .bp-contact-resources > summary { position: relative; }
|
|
476
|
+
html body[data-bot-product-ui] .bp-contact-unread-dot { position: absolute; top: 4px; right: 4px; width: 6px; height: 6px; border-radius: 50%; background: var(--bp-chat-accent, #5174a0); }
|
|
477
|
+
html body[data-bot-product-ui] .bp-contact-unread-count { margin-left: auto; font-size: 11px; font-weight: 650; }
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { observedRequestIds, readSendOutcome } from './composer-draft-witness.mjs'
|
|
2
|
+
|
|
3
|
+
// Read-only adapter for the public SessionBinding: no prompt interception,
|
|
4
|
+
// retention, replacement, or access to the concrete Session implementation.
|
|
5
|
+
export function createComposerDraftBinding(binding) {
|
|
6
|
+
const session = binding?.session, events = binding?.eventSource
|
|
7
|
+
if (typeof session?.getSnapshot !== 'function' || typeof session?.subscribe !== 'function' ||
|
|
8
|
+
typeof events?.getSnapshot !== 'function' || typeof events?.subscribe !== 'function') return null
|
|
9
|
+
const inbox = session.projections?.faceOf?.('inbox')
|
|
10
|
+
const echoes = new Map(), accepted = new Set(), listeners = new Set()
|
|
11
|
+
let snapshot, serialized = '', releases = []
|
|
12
|
+
const collect = () => {
|
|
13
|
+
for (const row of session.getSnapshot()?.pendingSubmissions ?? []) {
|
|
14
|
+
if (typeof row?.requestId === 'string' && row.requestId) echoes.set(row.requestId, {
|
|
15
|
+
requestId: row.requestId, text: row.text, time: row.time,
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
for (const id of observedRequestIds((events.getSnapshot()?.entries ?? [])
|
|
19
|
+
.filter(row => row.type === 'event').map(row => row.event))) accepted.add(id)
|
|
20
|
+
// Queue acceptance is also durable admission. Read only the published
|
|
21
|
+
// inbox projection, using the same UserMessage source identity as the SDK.
|
|
22
|
+
const queue = inbox?.getSnapshot?.()
|
|
23
|
+
for (const target of ['next-turn', 'next-step']) for (const message of queue?.[target] ?? []) {
|
|
24
|
+
if (message?.source?.kind === 'user' && typeof message.source.rpcId === 'string') accepted.add(message.source.rpcId)
|
|
25
|
+
}
|
|
26
|
+
while (echoes.size > 128) echoes.delete(echoes.keys().next().value)
|
|
27
|
+
while (accepted.size > 512) accepted.delete(accepted.values().next().value)
|
|
28
|
+
const value = { pendingSubmissions: [...echoes.values()], acceptedRequestIds: [...accepted] }
|
|
29
|
+
const next = JSON.stringify(value)
|
|
30
|
+
if (next === serialized) return
|
|
31
|
+
serialized = next; snapshot = value
|
|
32
|
+
for (const listener of [...listeners]) listener()
|
|
33
|
+
}
|
|
34
|
+
collect()
|
|
35
|
+
return Object.freeze({
|
|
36
|
+
getSnapshot: () => snapshot,
|
|
37
|
+
subscribe(listener) {
|
|
38
|
+
listeners.add(listener)
|
|
39
|
+
if (listeners.size === 1) {
|
|
40
|
+
releases = [session.subscribe(collect), events.subscribe(collect), inbox?.subscribe?.(collect)].filter(value => typeof value === 'function')
|
|
41
|
+
collect()
|
|
42
|
+
}
|
|
43
|
+
return () => {
|
|
44
|
+
listeners.delete(listener)
|
|
45
|
+
if (!listeners.size) { for (const release of releases) release(); releases = [] }
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
outcome(pending) { collect(); return readSendOutcome({ pending, acceptedRequestIds: snapshot.acceptedRequestIds }) },
|
|
49
|
+
})
|
|
50
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createElement as h, useMemo, useSyncExternalStore } from 'react'
|
|
2
|
+
import { createComposerDraftBinding } from './composer-draft-binding.mjs'
|
|
3
|
+
import { ComposerDraft } from './composer-draft-session.jsx'
|
|
4
|
+
|
|
5
|
+
function Bound({ control, ...props }) {
|
|
6
|
+
const snapshot = useSyncExternalStore(control.subscribe, control.getSnapshot, control.getSnapshot)
|
|
7
|
+
const useSubmissions = select => select(snapshot)
|
|
8
|
+
return h(ComposerDraft, { ...props, useSubmissions, witness: control.outcome, evidenceRevision: snapshot })
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function ComposerDraftBound({ sessionBinding, ...props }) {
|
|
12
|
+
const control = useMemo(() => createComposerDraftBinding(sessionBinding), [sessionBinding])
|
|
13
|
+
return control ? h(Bound, { ...props, control }) : h(ComposerDraft, props)
|
|
14
|
+
}
|