@antelopejs/dms-ai 0.1.4 → 0.1.6
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/README.md +55 -29
- package/dist/channels/bridge.d.ts +2 -8
- package/dist/channels/bridge.js +26 -42
- package/dist/channels/bridge.js.map +1 -1
- package/dist/channels/channel-service.d.ts +2 -2
- package/dist/channels/channel-service.js +12 -31
- package/dist/channels/channel-service.js.map +1 -1
- package/dist/channels/registry.d.ts +2 -2
- package/dist/channels/registry.js +7 -7
- package/dist/channels/registry.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +8 -1
- package/dist/config.js.map +1 -1
- package/dist/constants/channels.d.ts +5 -10
- package/dist/constants/channels.js +6 -10
- package/dist/constants/channels.js.map +1 -1
- package/dist/constants/sidecar.d.ts +5 -1
- package/dist/constants/sidecar.js +6 -2
- package/dist/constants/sidecar.js.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/build-id.d.ts +1 -0
- package/dist/lifecycle/build-id.js +32 -0
- package/dist/lifecycle/build-id.js.map +1 -0
- package/dist/lifecycle/sidecar-owner.d.ts +13 -0
- package/dist/lifecycle/sidecar-owner.js +89 -0
- package/dist/lifecycle/sidecar-owner.js.map +1 -0
- package/dist/lifecycle/sidecar-socket.d.ts +1 -1
- package/dist/lifecycle/sidecar-socket.js +2 -2
- package/dist/lifecycle/sidecar-socket.js.map +1 -1
- package/dist/lifecycle/spawn-sidecar.d.ts +0 -1
- package/dist/lifecycle/spawn-sidecar.js +51 -159
- package/dist/lifecycle/spawn-sidecar.js.map +1 -1
- package/dist/lifecycle/terminate-process.d.ts +1 -0
- package/dist/lifecycle/terminate-process.js +34 -0
- package/dist/lifecycle/terminate-process.js.map +1 -0
- package/dist/routes/channels.d.ts +3 -3
- package/dist/routes/channels.js +11 -12
- package/dist/routes/channels.js.map +1 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/index.js.map +1 -1
- package/frontend-vue/.prettierignore +3 -0
- package/frontend-vue/.prettierrc +10 -0
- package/frontend-vue/app/chat/components/ChatView.vue +582 -0
- package/frontend-vue/app/chat/components/ComposerInput.vue +742 -0
- package/frontend-vue/app/chat/components/ConnectionBanner.vue +105 -0
- package/frontend-vue/app/chat/components/ConversationDrawer.vue +266 -0
- package/frontend-vue/app/chat/components/MarkdownContent.vue +196 -0
- package/frontend-vue/app/chat/components/MessageList.vue +474 -0
- package/frontend-vue/app/chat/components/PermissionRequests.vue +323 -0
- package/frontend-vue/app/chat/components/QuestionPrompt.vue +275 -0
- package/frontend-vue/app/chat/components/QueuedMessages.vue +109 -0
- package/frontend-vue/app/chat/components/TodoList.vue +291 -0
- package/frontend-vue/app/chat/components/ToolCallEntry.vue +218 -0
- package/frontend-vue/app/chat/components/ToolCluster.vue +282 -0
- package/frontend-vue/app/chat/composables/useChatChannel.ts +116 -0
- package/frontend-vue/app/chat/composables/useConversation.ts +838 -0
- package/frontend-vue/app/chat/composables/useConversationId.ts +34 -0
- package/frontend-vue/app/chat/composables/useConversationList.ts +56 -0
- package/frontend-vue/app/chat/composables/usePermissionQueue.ts +59 -0
- package/frontend-vue/app/chat/composables/useQuestionQueue.ts +50 -0
- package/frontend-vue/app/chat/composables/useRunClock.ts +28 -0
- package/frontend-vue/app/chat/composables/useSettings.ts +67 -0
- package/frontend-vue/app/chat/constants/attachments.ts +16 -0
- package/frontend-vue/app/chat/constants/connection-banner.ts +7 -0
- package/frontend-vue/app/chat/constants/conversation-drawer.ts +13 -0
- package/frontend-vue/app/chat/constants/conversation.ts +75 -0
- package/frontend-vue/app/chat/constants/permissions.ts +50 -0
- package/frontend-vue/app/chat/constants/protocol.ts +48 -0
- package/frontend-vue/app/chat/constants/run-status.ts +50 -0
- package/frontend-vue/app/chat/constants/settings.ts +60 -0
- package/frontend-vue/app/chat/types/conversation.ts +87 -0
- package/frontend-vue/app/chat/types/permission.ts +7 -0
- package/frontend-vue/app/chat/types/question.ts +17 -0
- package/frontend-vue/app/chat/types/settings.ts +27 -0
- package/frontend-vue/app/chat/utils/attachments.ts +62 -0
- package/frontend-vue/app/chat/utils/format.ts +14 -0
- package/frontend-vue/app/chat/utils/ids.ts +34 -0
- package/frontend-vue/app/chat/utils/markdown.ts +188 -0
- package/frontend-vue/app/chat/utils/run-status.ts +90 -0
- package/frontend-vue/app/chat/utils/todos.ts +64 -0
- package/frontend-vue/app/chat/utils/tool-summary.ts +53 -0
- package/frontend-vue/app/components/ActivityView.vue +34 -34
- package/frontend-vue/app/components/ChatPanel.vue +276 -0
- package/frontend-vue/app/components/SettingsView.vue +120 -112
- package/frontend-vue/app/components/SkillsView.vue +55 -53
- package/frontend-vue/app/plugins/ai.client.ts +145 -129
- package/frontend-vue/app/runtime/assistant-session.ts +21 -0
- package/frontend-vue/app/runtime/backoff.ts +11 -14
- package/frontend-vue/app/runtime/channel-client.ts +130 -141
- package/frontend-vue/app/runtime/chat-transport.ts +25 -55
- package/frontend-vue/app/runtime/constants.ts +69 -59
- package/frontend-vue/app/runtime/current-page.ts +49 -15
- package/frontend-vue/app/runtime/event-stream.ts +35 -35
- package/frontend-vue/app/runtime/frame-router.ts +30 -0
- package/frontend-vue/app/runtime/header-action.ts +18 -18
- package/frontend-vue/app/runtime/host-commands.ts +57 -56
- package/frontend-vue/app/runtime/listeners.ts +31 -0
- package/frontend-vue/app/runtime/navigation-complete.ts +7 -7
- package/frontend-vue/app/runtime/overlay-prefs.ts +36 -36
- package/frontend-vue/app/runtime/panel-state.ts +88 -0
- package/frontend-vue/app/runtime/session-gate.ts +8 -8
- package/frontend-vue/app/runtime/shortcuts.ts +12 -12
- package/frontend-vue/app/runtime/sidecar-status.ts +61 -61
- package/frontend-vue/app/runtime/typed-message.ts +11 -0
- package/frontend-vue/dms.frontend.ts +12 -12
- package/frontend-vue/eslint.config.mjs +13 -13
- package/frontend-vue/package.json +11 -4
- package/frontend-vue/pnpm-lock.yaml +298 -96
- package/frontend-vue/tests/backoff.test.ts +26 -30
- package/frontend-vue/tests/channel-client.test.ts +187 -188
- package/frontend-vue/tests/chat/markdown.test.ts +271 -0
- package/frontend-vue/tests/chat/useChatChannel.test.ts +124 -0
- package/frontend-vue/tests/chat/useConversation.test.ts +283 -0
- package/frontend-vue/tests/chat-panel.test.ts +354 -0
- package/frontend-vue/tests/chat-transport.test.ts +84 -57
- package/frontend-vue/tests/host-commands.test.ts +126 -87
- package/frontend-vue/tests/navigation.test.ts +65 -34
- package/frontend-vue/tests/overlay-prefs.test.ts +49 -49
- package/frontend-vue/tests/panel-state.test.ts +58 -0
- package/frontend-vue/tests/session-gate.test.ts +33 -33
- package/frontend-vue/tests/sidecar-guest.test.ts +46 -46
- package/frontend-vue/tests/sidecar-status.test.ts +29 -29
- package/frontend-vue/tsconfig.chat.json +16 -0
- package/frontend-vue/vitest.config.ts +6 -4
- package/package.json +6 -5
- package/sidecar/dist/agent/effective-mode.d.ts +2 -2
- package/sidecar/dist/agent/effective-mode.js +1 -1
- package/sidecar/dist/agent/effective-mode.js.map +1 -1
- package/sidecar/dist/agent/host-context.js +7 -9
- package/sidecar/dist/agent/host-context.js.map +1 -1
- package/sidecar/dist/agent/permission-bus.d.ts +1 -1
- package/sidecar/dist/agent/permission-bus.js +2 -2
- package/sidecar/dist/agent/permission-bus.js.map +1 -1
- package/sidecar/dist/agent/provider.d.ts +2 -2
- package/sidecar/dist/agent/question-bus.d.ts +1 -1
- package/sidecar/dist/agent/question-bus.js +2 -2
- package/sidecar/dist/agent/question-bus.js.map +1 -1
- package/sidecar/dist/agent/runner.d.ts +2 -2
- package/sidecar/dist/agent/runner.js +24 -8
- package/sidecar/dist/agent/runner.js.map +1 -1
- package/sidecar/dist/agent/session.d.ts +2 -2
- package/sidecar/dist/agent/session.js +49 -9
- package/sidecar/dist/agent/session.js.map +1 -1
- package/sidecar/dist/agent/switching-runner.js +10 -5
- package/sidecar/dist/agent/switching-runner.js.map +1 -1
- package/sidecar/dist/agent/turn-end-reasons.d.ts +2 -0
- package/sidecar/dist/agent/turn-end-reasons.js +6 -1
- package/sidecar/dist/agent/turn-end-reasons.js.map +1 -1
- package/sidecar/dist/constants/agent.d.ts +4 -1
- package/sidecar/dist/constants/agent.js +4 -1
- package/sidecar/dist/constants/agent.js.map +1 -1
- package/sidecar/dist/constants/cli.d.ts +0 -1
- package/sidecar/dist/constants/cli.js +0 -1
- package/sidecar/dist/constants/cli.js.map +1 -1
- package/sidecar/dist/constants/codex.d.ts +5 -2
- package/sidecar/dist/constants/codex.js +5 -2
- package/sidecar/dist/constants/codex.js.map +1 -1
- package/sidecar/dist/constants/http.d.ts +0 -9
- package/sidecar/dist/constants/http.js +0 -19
- package/sidecar/dist/constants/http.js.map +1 -1
- package/sidecar/dist/constants/mcp.d.ts +1 -1
- package/sidecar/dist/constants/mcp.js +1 -1
- package/sidecar/dist/constants/mcp.js.map +1 -1
- package/sidecar/dist/constants/paths.d.ts +0 -1
- package/sidecar/dist/constants/paths.js +0 -1
- package/sidecar/dist/constants/paths.js.map +1 -1
- package/sidecar/dist/constants/ws.d.ts +3 -4
- package/sidecar/dist/constants/ws.js +3 -4
- package/sidecar/dist/constants/ws.js.map +1 -1
- package/sidecar/dist/index.d.ts +4 -1
- package/sidecar/dist/index.js +13 -13
- package/sidecar/dist/index.js.map +1 -1
- package/sidecar/dist/mcp/tools/find-pages-using.js +5 -10
- package/sidecar/dist/mcp/tools/find-pages-using.js.map +1 -1
- package/sidecar/dist/mcp/types.d.ts +1 -1
- package/sidecar/dist/pages/page-filepath.d.ts +4 -0
- package/sidecar/dist/pages/page-filepath.js +28 -0
- package/sidecar/dist/pages/page-filepath.js.map +1 -0
- package/sidecar/dist/prompts/agent.d.ts +1 -1
- package/sidecar/dist/prompts/agent.js +1 -1
- package/sidecar/dist/prompts/agent.js.map +1 -1
- package/sidecar/dist/protocol/events.js +2 -2
- package/sidecar/dist/protocol/events.js.map +1 -1
- package/sidecar/dist/protocol/messages.d.ts +4 -15
- package/sidecar/dist/protocol/messages.js +4 -11
- package/sidecar/dist/protocol/messages.js.map +1 -1
- package/sidecar/dist/providers/claude/config.d.ts +2 -2
- package/sidecar/dist/providers/claude/config.js +2 -2
- package/sidecar/dist/providers/claude/config.js.map +1 -1
- package/sidecar/dist/providers/claude/provider.js +1 -1
- package/sidecar/dist/providers/claude/provider.js.map +1 -1
- package/sidecar/dist/providers/codex/config.d.ts +3 -2
- package/sidecar/dist/providers/codex/config.js +3 -3
- package/sidecar/dist/providers/codex/config.js.map +1 -1
- package/sidecar/dist/providers/codex/process.js +107 -74
- package/sidecar/dist/providers/codex/process.js.map +1 -1
- package/sidecar/dist/providers/codex/provider.js +68 -31
- package/sidecar/dist/providers/codex/provider.js.map +1 -1
- package/sidecar/dist/providers/codex/skills.d.ts +1 -0
- package/sidecar/dist/providers/codex/skills.js +4 -1
- package/sidecar/dist/providers/codex/skills.js.map +1 -1
- package/sidecar/dist/providers/codex/stop.d.ts +4 -0
- package/sidecar/dist/providers/codex/stop.js +71 -0
- package/sidecar/dist/providers/codex/stop.js.map +1 -0
- package/sidecar/dist/server/{iframe-socket-registry.d.ts → chat-socket-registry.d.ts} +3 -2
- package/sidecar/dist/server/{iframe-socket-registry.js → chat-socket-registry.js} +4 -3
- package/sidecar/dist/server/chat-socket-registry.js.map +1 -0
- package/sidecar/dist/server/client-auth.js +2 -14
- package/sidecar/dist/server/client-auth.js.map +1 -1
- package/sidecar/dist/server/host-command-router.d.ts +5 -0
- package/sidecar/dist/server/host-command-router.js +4 -0
- package/sidecar/dist/server/host-command-router.js.map +1 -0
- package/sidecar/dist/server/host-socket-registry.d.ts +1 -1
- package/sidecar/dist/server/host-socket-registry.js +16 -13
- package/sidecar/dist/server/host-socket-registry.js.map +1 -1
- package/sidecar/dist/server/http.d.ts +0 -1
- package/sidecar/dist/server/http.js +1 -44
- package/sidecar/dist/server/http.js.map +1 -1
- package/sidecar/dist/server/routing.d.ts +5 -6
- package/sidecar/dist/server/routing.js +18 -28
- package/sidecar/dist/server/routing.js.map +1 -1
- package/sidecar/dist/server/ws.d.ts +2 -2
- package/sidecar/dist/server/ws.js +41 -39
- package/sidecar/dist/server/ws.js.map +1 -1
- package/sidecar/dist/state/host-state.d.ts +10 -2
- package/sidecar/dist/state/host-state.js +13 -3
- package/sidecar/dist/state/host-state.js.map +1 -1
- package/sidecar/dist/state/settings-store.js +2 -2
- package/sidecar/dist/state/settings-store.js.map +1 -1
- package/sidecar/dist/state/settings-types.d.ts +3 -3
- package/sidecar/dist/state/settings-types.js +1 -1
- package/sidecar/dist/state/settings-types.js.map +1 -1
- package/sidecar/package.json +3 -5
- package/dist/chatbox/passthrough.d.ts +0 -3
- package/dist/chatbox/passthrough.js +0 -53
- package/dist/chatbox/passthrough.js.map +0 -1
- package/dist/constants/chatbox.d.ts +0 -10
- package/dist/constants/chatbox.js +0 -35
- package/dist/constants/chatbox.js.map +0 -1
- package/dist/routes/chatbox.d.ts +0 -7
- package/dist/routes/chatbox.js +0 -47
- package/dist/routes/chatbox.js.map +0 -1
- package/frontend-vue/app/runtime/overlay.ts +0 -400
- package/frontend-vue/app/runtime/theme-bridge.ts +0 -189
- package/sidecar/chatbox/dist/assets/index-C8u7mkHn.css +0 -1
- package/sidecar/chatbox/dist/assets/index-tdZvY7ee.js +0 -52
- package/sidecar/chatbox/dist/index.html +0 -13
- package/sidecar/dist/server/iframe-socket-registry.js.map +0 -1
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
// Theme bridge (host → chatbox iframe). The host DMS is the source of truth for
|
|
2
|
-
// the active Nuxt UI primary palette and the light/dark mode; the chatbox iframe
|
|
3
|
-
// is a separate document, so it cannot inherit them through CSS — we forward
|
|
4
|
-
// them explicitly here. Both documents share the dashboard's origin, which is
|
|
5
|
-
// the only one either side posts to or accepts messages from.
|
|
6
|
-
//
|
|
7
|
-
// Protocol:
|
|
8
|
-
// iframe → host : { type: "dms-ai:ready" } (chatbox announces mount)
|
|
9
|
-
// host → iframe : { type: "dms-ai:theme", mode, primary }
|
|
10
|
-
// See sidecar/chatbox/src/composables/useHostTheme.ts for the receiver.
|
|
11
|
-
|
|
12
|
-
const THEME_MESSAGE_TYPE = 'dms-ai:theme'
|
|
13
|
-
const READY_MESSAGE_TYPE = 'dms-ai:ready'
|
|
14
|
-
|
|
15
|
-
const PRIMARY_STEPS = [
|
|
16
|
-
'50',
|
|
17
|
-
'100',
|
|
18
|
-
'200',
|
|
19
|
-
'300',
|
|
20
|
-
'400',
|
|
21
|
-
'500',
|
|
22
|
-
'600',
|
|
23
|
-
'700',
|
|
24
|
-
'800',
|
|
25
|
-
'900',
|
|
26
|
-
'950',
|
|
27
|
-
] as const
|
|
28
|
-
|
|
29
|
-
// Nuxt UI semantic surface/text/border tokens. The host DMS may override these
|
|
30
|
-
// with bespoke values (e.g. the DMS dark canvas is #0a0b12, not the default
|
|
31
|
-
// neutral-900), so the chatbox can't just rely on the default neutral palette —
|
|
32
|
-
// it has to mirror the host's resolved values for a faithful match in both modes.
|
|
33
|
-
const SEMANTIC_TOKENS = [
|
|
34
|
-
'--ui-bg',
|
|
35
|
-
'--ui-bg-muted',
|
|
36
|
-
'--ui-bg-elevated',
|
|
37
|
-
'--ui-bg-accented',
|
|
38
|
-
'--ui-bg-inverted',
|
|
39
|
-
'--ui-text-dimmed',
|
|
40
|
-
'--ui-text-muted',
|
|
41
|
-
'--ui-text-toned',
|
|
42
|
-
'--ui-text',
|
|
43
|
-
'--ui-text-highlighted',
|
|
44
|
-
'--ui-text-inverted',
|
|
45
|
-
'--ui-border',
|
|
46
|
-
'--ui-border-muted',
|
|
47
|
-
'--ui-border-accented',
|
|
48
|
-
'--ui-border-inverted',
|
|
49
|
-
] as const
|
|
50
|
-
|
|
51
|
-
export interface HostTheme {
|
|
52
|
-
mode: 'dark' | 'light'
|
|
53
|
-
primary: Record<string, string>
|
|
54
|
-
tokens: Record<string, string>
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function readHostMode(): 'dark' | 'light' {
|
|
58
|
-
return document.documentElement.classList.contains('dark') ? 'dark' : 'light'
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
interface ResolvedColors {
|
|
62
|
-
primary: Record<string, string>
|
|
63
|
-
tokens: Record<string, string>
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Resolve CSS custom properties to concrete color strings. They are authored as
|
|
67
|
-
// `var(--color-…)` chains, so we read them through a throwaway probe whose
|
|
68
|
-
// computed `color` forces full var() resolution (getComputedStyle on the custom
|
|
69
|
-
// property itself may return the unresolved `var(...)` token in some browsers).
|
|
70
|
-
// A variable the host does not define is skipped entirely: `color: var(--undef)`
|
|
71
|
-
// falls back to the *inherited* color, so the probe would otherwise report a
|
|
72
|
-
// bogus concrete value (e.g. black) instead of "missing" — leaving downstream
|
|
73
|
-
// guards/fallbacks ineffective.
|
|
74
|
-
function readResolvedColors(): ResolvedColors {
|
|
75
|
-
const rootStyle = getComputedStyle(document.documentElement)
|
|
76
|
-
const probe = document.createElement('span')
|
|
77
|
-
probe.style.cssText =
|
|
78
|
-
'position:absolute;width:0;height:0;overflow:hidden;visibility:hidden;pointer-events:none;'
|
|
79
|
-
document.body.appendChild(probe)
|
|
80
|
-
const probeStyle = getComputedStyle(probe)
|
|
81
|
-
const resolve = (name: string): string => {
|
|
82
|
-
if (rootStyle.getPropertyValue(name).trim() === '') return ''
|
|
83
|
-
probe.style.color = `var(${name})`
|
|
84
|
-
return probeStyle.color
|
|
85
|
-
}
|
|
86
|
-
const primary: Record<string, string> = {}
|
|
87
|
-
for (const step of PRIMARY_STEPS) {
|
|
88
|
-
const value = resolve(`--ui-color-primary-${step}`)
|
|
89
|
-
if (value !== '') primary[step] = value
|
|
90
|
-
}
|
|
91
|
-
const tokens: Record<string, string> = {}
|
|
92
|
-
for (const name of SEMANTIC_TOKENS) {
|
|
93
|
-
const value = resolve(name)
|
|
94
|
-
if (value !== '') tokens[name] = value
|
|
95
|
-
}
|
|
96
|
-
probe.remove()
|
|
97
|
-
return { primary, tokens }
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function readHostTheme(): HostTheme {
|
|
101
|
-
const { primary, tokens } = readResolvedColors()
|
|
102
|
-
return { mode: readHostMode(), primary, tokens }
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function themeSignature(theme: HostTheme): string {
|
|
106
|
-
const primary = PRIMARY_STEPS.map((s) => theme.primary[s]).join(',')
|
|
107
|
-
const tokens = SEMANTIC_TOKENS.map((t) => theme.tokens[t]).join(',')
|
|
108
|
-
return `${theme.mode}|${primary}|${tokens}`
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
interface MessageData {
|
|
112
|
-
type?: unknown
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
type ThemePush = (force: boolean) => void
|
|
116
|
-
|
|
117
|
-
/** True for a message the chatbox frame itself posted, from our own origin. */
|
|
118
|
-
export function isFromFrame(
|
|
119
|
-
event: MessageEvent,
|
|
120
|
-
iframe: HTMLIFrameElement,
|
|
121
|
-
): boolean {
|
|
122
|
-
return (
|
|
123
|
-
event.source === iframe.contentWindow &&
|
|
124
|
-
event.origin === globalThis.location.origin
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Only answer the handshake from our own iframe, never an arbitrary frame.
|
|
129
|
-
function answerReadyHandshake(
|
|
130
|
-
iframe: HTMLIFrameElement,
|
|
131
|
-
post: ThemePush,
|
|
132
|
-
): void {
|
|
133
|
-
globalThis.addEventListener('message', (event: MessageEvent) => {
|
|
134
|
-
const type = (event.data as MessageData)?.type
|
|
135
|
-
if (type === READY_MESSAGE_TYPE && isFromFrame(event, iframe)) {
|
|
136
|
-
post(true)
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// @nuxtjs/color-mode toggles `.dark` on <html>; mirror those changes live.
|
|
142
|
-
function watchHostModeChanges(post: ThemePush): void {
|
|
143
|
-
const observer = new MutationObserver(() => post(false))
|
|
144
|
-
observer.observe(document.documentElement, {
|
|
145
|
-
attributes: true,
|
|
146
|
-
attributeFilter: ['class'],
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Wire the bridge to a chatbox iframe: reply to its `ready` handshake and
|
|
151
|
-
// re-push the theme whenever the host flips light/dark. Primary/token swaps
|
|
152
|
-
// alone are not mirrored live — they only reach the iframe on the forced
|
|
153
|
-
// pushes (`ready` handshake and iframe `load`).
|
|
154
|
-
// `onTheme` fires on every (re)push so the caller can keep host-side chrome
|
|
155
|
-
// (the overlay backdrop / iframe color-scheme) in sync with live mode changes —
|
|
156
|
-
// without it, an OS-driven dark switch leaves the panel edge on its old shade
|
|
157
|
-
// until the page is reloaded.
|
|
158
|
-
export function installThemeBridge(
|
|
159
|
-
iframe: HTMLIFrameElement,
|
|
160
|
-
onTheme?: (theme: HostTheme) => void,
|
|
161
|
-
): void {
|
|
162
|
-
let lastMode: 'dark' | 'light' | '' = ''
|
|
163
|
-
let lastSignature = ''
|
|
164
|
-
|
|
165
|
-
const post: ThemePush = (force) => {
|
|
166
|
-
// The observer fires on any <html> class mutation (scroll locks, modal or
|
|
167
|
-
// route classes…). Gate the expensive probe resolution behind a cheap mode
|
|
168
|
-
// check: only a light/dark flip changes what this bridge mirrors live, and
|
|
169
|
-
// primary/token swaps are re-pushed on the `force` paths (ready/load).
|
|
170
|
-
const mode = readHostMode()
|
|
171
|
-
if (!force && mode === lastMode) return
|
|
172
|
-
lastMode = mode
|
|
173
|
-
const theme = readHostTheme()
|
|
174
|
-
const signature = themeSignature(theme)
|
|
175
|
-
if (!force && signature === lastSignature) return
|
|
176
|
-
lastSignature = signature
|
|
177
|
-
onTheme?.(theme)
|
|
178
|
-
iframe.contentWindow?.postMessage(
|
|
179
|
-
{ type: THEME_MESSAGE_TYPE, ...theme },
|
|
180
|
-
globalThis.location.origin,
|
|
181
|
-
)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
answerReadyHandshake(iframe, post)
|
|
185
|
-
watchHostModeChanges(post)
|
|
186
|
-
// Belt and suspenders for the case where the iframe loaded before its
|
|
187
|
-
// message listener was ready and the `ready` handshake was missed.
|
|
188
|
-
iframe.addEventListener('load', () => post(true))
|
|
189
|
-
}
|