@schlessera/brain-ui-react 0.4.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/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/components/chat/ask-user-card.d.ts +12 -0
- package/dist/components/chat/ask-user-card.d.ts.map +1 -0
- package/dist/components/chat/ask-user-card.js +185 -0
- package/dist/components/chat/ask-user-card.js.map +1 -0
- package/dist/components/chat/brain-markdown.d.ts +35 -0
- package/dist/components/chat/brain-markdown.d.ts.map +1 -0
- package/dist/components/chat/brain-markdown.js +363 -0
- package/dist/components/chat/brain-markdown.js.map +1 -0
- package/dist/components/chat/chat-page.d.ts +2 -0
- package/dist/components/chat/chat-page.d.ts.map +1 -0
- package/dist/components/chat/chat-page.js +442 -0
- package/dist/components/chat/chat-page.js.map +1 -0
- package/dist/components/chat/command-palette.d.ts +5 -0
- package/dist/components/chat/command-palette.d.ts.map +1 -0
- package/dist/components/chat/command-palette.js +18 -0
- package/dist/components/chat/command-palette.js.map +1 -0
- package/dist/components/chat/markdown-content.d.ts +4 -0
- package/dist/components/chat/markdown-content.d.ts.map +1 -0
- package/dist/components/chat/markdown-content.js +6 -0
- package/dist/components/chat/markdown-content.js.map +1 -0
- package/dist/components/chat/message-bubble.d.ts +9 -0
- package/dist/components/chat/message-bubble.d.ts.map +1 -0
- package/dist/components/chat/message-bubble.js +129 -0
- package/dist/components/chat/message-bubble.js.map +1 -0
- package/dist/components/chat/message-share.d.ts +10 -0
- package/dist/components/chat/message-share.d.ts.map +1 -0
- package/dist/components/chat/message-share.js +65 -0
- package/dist/components/chat/message-share.js.map +1 -0
- package/dist/components/chat/renderers/claude-tools.d.ts +3 -0
- package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -0
- package/dist/components/chat/renderers/claude-tools.js +38 -0
- package/dist/components/chat/renderers/claude-tools.js.map +1 -0
- package/dist/components/chat/renderers/generic.d.ts +9 -0
- package/dist/components/chat/renderers/generic.d.ts.map +1 -0
- package/dist/components/chat/renderers/generic.js +68 -0
- package/dist/components/chat/renderers/generic.js.map +1 -0
- package/dist/components/chat/renderers/index.d.ts +5 -0
- package/dist/components/chat/renderers/index.d.ts.map +1 -0
- package/dist/components/chat/renderers/index.js +17 -0
- package/dist/components/chat/renderers/index.js.map +1 -0
- package/dist/components/chat/risk-hints.d.ts +20 -0
- package/dist/components/chat/risk-hints.d.ts.map +1 -0
- package/dist/components/chat/risk-hints.js +81 -0
- package/dist/components/chat/risk-hints.js.map +1 -0
- package/dist/components/chat/session-drawer.d.ts +6 -0
- package/dist/components/chat/session-drawer.d.ts.map +1 -0
- package/dist/components/chat/session-drawer.js +96 -0
- package/dist/components/chat/session-drawer.js.map +1 -0
- package/dist/components/chat/share-block.d.ts +9 -0
- package/dist/components/chat/share-block.d.ts.map +1 -0
- package/dist/components/chat/share-block.js +70 -0
- package/dist/components/chat/share-block.js.map +1 -0
- package/dist/components/chat/tool-call-timeline.d.ts +8 -0
- package/dist/components/chat/tool-call-timeline.d.ts.map +1 -0
- package/dist/components/chat/tool-call-timeline.js +100 -0
- package/dist/components/chat/tool-call-timeline.js.map +1 -0
- package/dist/components/chat/tool-views.d.ts +116 -0
- package/dist/components/chat/tool-views.d.ts.map +1 -0
- package/dist/components/chat/tool-views.js +628 -0
- package/dist/components/chat/tool-views.js.map +1 -0
- package/dist/components/chat/welcome-state.d.ts +4 -0
- package/dist/components/chat/welcome-state.d.ts.map +1 -0
- package/dist/components/chat/welcome-state.js +10 -0
- package/dist/components/chat/welcome-state.js.map +1 -0
- package/dist/components/connectivity/connection-gate.d.ts +5 -0
- package/dist/components/connectivity/connection-gate.d.ts.map +1 -0
- package/dist/components/connectivity/connection-gate.js +42 -0
- package/dist/components/connectivity/connection-gate.js.map +1 -0
- package/dist/components/connectivity/login-screen.d.ts +9 -0
- package/dist/components/connectivity/login-screen.d.ts.map +1 -0
- package/dist/components/connectivity/login-screen.js +99 -0
- package/dist/components/connectivity/login-screen.js.map +1 -0
- package/dist/components/files/file-panel.d.ts +5 -0
- package/dist/components/files/file-panel.d.ts.map +1 -0
- package/dist/components/files/file-panel.js +46 -0
- package/dist/components/files/file-panel.js.map +1 -0
- package/dist/components/files/file-tree.d.ts +2 -0
- package/dist/components/files/file-tree.d.ts.map +1 -0
- package/dist/components/files/file-tree.js +63 -0
- package/dist/components/files/file-tree.js.map +1 -0
- package/dist/components/files/file-viewer-binary.d.ts +5 -0
- package/dist/components/files/file-viewer-binary.d.ts.map +1 -0
- package/dist/components/files/file-viewer-binary.js +20 -0
- package/dist/components/files/file-viewer-binary.js.map +1 -0
- package/dist/components/files/file-viewer-html.d.ts +4 -0
- package/dist/components/files/file-viewer-html.d.ts.map +1 -0
- package/dist/components/files/file-viewer-html.js +5 -0
- package/dist/components/files/file-viewer-html.js.map +1 -0
- package/dist/components/files/file-viewer-markdown.d.ts +4 -0
- package/dist/components/files/file-viewer-markdown.d.ts.map +1 -0
- package/dist/components/files/file-viewer-markdown.js +10 -0
- package/dist/components/files/file-viewer-markdown.js.map +1 -0
- package/dist/components/files/file-viewer-raw.d.ts +5 -0
- package/dist/components/files/file-viewer-raw.d.ts.map +1 -0
- package/dist/components/files/file-viewer-raw.js +15 -0
- package/dist/components/files/file-viewer-raw.js.map +1 -0
- package/dist/components/files/file-viewer.d.ts +2 -0
- package/dist/components/files/file-viewer.d.ts.map +1 -0
- package/dist/components/files/file-viewer.js +175 -0
- package/dist/components/files/file-viewer.js.map +1 -0
- package/dist/components/files/frontmatter-panel.d.ts +5 -0
- package/dist/components/files/frontmatter-panel.d.ts.map +1 -0
- package/dist/components/files/frontmatter-panel.js +12 -0
- package/dist/components/files/frontmatter-panel.js.map +1 -0
- package/dist/components/layout/app-shell.d.ts +5 -0
- package/dist/components/layout/app-shell.d.ts.map +1 -0
- package/dist/components/layout/app-shell.js +10 -0
- package/dist/components/layout/app-shell.js.map +1 -0
- package/dist/components/layout/mobile-tab-bar.d.ts +2 -0
- package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -0
- package/dist/components/layout/mobile-tab-bar.js +16 -0
- package/dist/components/layout/mobile-tab-bar.js.map +1 -0
- package/dist/components/layout/side-rail.d.ts +2 -0
- package/dist/components/layout/side-rail.d.ts.map +1 -0
- package/dist/components/layout/side-rail.js +26 -0
- package/dist/components/layout/side-rail.js.map +1 -0
- package/dist/components/layout/slide-panel.d.ts +9 -0
- package/dist/components/layout/slide-panel.d.ts.map +1 -0
- package/dist/components/layout/slide-panel.js +18 -0
- package/dist/components/layout/slide-panel.js.map +1 -0
- package/dist/components/quick-actions/streaming-modal.d.ts +8 -0
- package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -0
- package/dist/components/quick-actions/streaming-modal.js +92 -0
- package/dist/components/quick-actions/streaming-modal.js.map +1 -0
- package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
- package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -0
- package/dist/components/quick-actions/whatsup-modal.js +82 -0
- package/dist/components/quick-actions/whatsup-modal.js.map +1 -0
- package/dist/components/settings/passkey-panel.d.ts +10 -0
- package/dist/components/settings/passkey-panel.d.ts.map +1 -0
- package/dist/components/settings/passkey-panel.js +118 -0
- package/dist/components/settings/passkey-panel.js.map +1 -0
- package/dist/components/share/share-menu.d.ts +23 -0
- package/dist/components/share/share-menu.d.ts.map +1 -0
- package/dist/components/share/share-menu.js +58 -0
- package/dist/components/share/share-menu.js.map +1 -0
- package/dist/components/voice/dictation-sheet.d.ts +6 -0
- package/dist/components/voice/dictation-sheet.d.ts.map +1 -0
- package/dist/components/voice/dictation-sheet.js +91 -0
- package/dist/components/voice/dictation-sheet.js.map +1 -0
- package/dist/components/voice/mic-button.d.ts +6 -0
- package/dist/components/voice/mic-button.d.ts.map +1 -0
- package/dist/components/voice/mic-button.js +9 -0
- package/dist/components/voice/mic-button.js.map +1 -0
- package/dist/components/voice/review-card.d.ts +8 -0
- package/dist/components/voice/review-card.d.ts.map +1 -0
- package/dist/components/voice/review-card.js +8 -0
- package/dist/components/voice/review-card.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -0
- package/dist/hooks/use-vpn-status.d.ts +2 -0
- package/dist/hooks/use-vpn-status.d.ts.map +1 -0
- package/dist/hooks/use-vpn-status.js +71 -0
- package/dist/hooks/use-vpn-status.js.map +1 -0
- package/dist/hooks/use-websocket.d.ts +8 -0
- package/dist/hooks/use-websocket.d.ts.map +1 -0
- package/dist/hooks/use-websocket.js +366 -0
- package/dist/hooks/use-websocket.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +115 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +70 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/backend.d.ts +7 -0
- package/dist/lib/backend.d.ts.map +1 -0
- package/dist/lib/backend.js +33 -0
- package/dist/lib/backend.js.map +1 -0
- package/dist/lib/frontmatter.d.ts +21 -0
- package/dist/lib/frontmatter.d.ts.map +1 -0
- package/dist/lib/frontmatter.js +88 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/image-attachments.d.ts +36 -0
- package/dist/lib/image-attachments.d.ts.map +1 -0
- package/dist/lib/image-attachments.js +175 -0
- package/dist/lib/image-attachments.js.map +1 -0
- package/dist/lib/passkeys.d.ts +18 -0
- package/dist/lib/passkeys.d.ts.map +1 -0
- package/dist/lib/passkeys.js +36 -0
- package/dist/lib/passkeys.js.map +1 -0
- package/dist/lib/share.d.ts +53 -0
- package/dist/lib/share.d.ts.map +1 -0
- package/dist/lib/share.js +144 -0
- package/dist/lib/share.js.map +1 -0
- package/dist/lib/strip-markdown.d.ts +10 -0
- package/dist/lib/strip-markdown.d.ts.map +1 -0
- package/dist/lib/strip-markdown.js +37 -0
- package/dist/lib/strip-markdown.js.map +1 -0
- package/dist/lib/tool-names.d.ts +17 -0
- package/dist/lib/tool-names.d.ts.map +1 -0
- package/dist/lib/tool-names.js +23 -0
- package/dist/lib/tool-names.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/ws-client.d.ts +26 -0
- package/dist/lib/ws-client.d.ts.map +1 -0
- package/dist/lib/ws-client.js +93 -0
- package/dist/lib/ws-client.js.map +1 -0
- package/dist/stores/chat-store.d.ts +131 -0
- package/dist/stores/chat-store.d.ts.map +1 -0
- package/dist/stores/chat-store.js +376 -0
- package/dist/stores/chat-store.js.map +1 -0
- package/dist/stores/connection-store.d.ts +11 -0
- package/dist/stores/connection-store.d.ts.map +1 -0
- package/dist/stores/connection-store.js +8 -0
- package/dist/stores/connection-store.js.map +1 -0
- package/dist/stores/file-store.d.ts +53 -0
- package/dist/stores/file-store.d.ts.map +1 -0
- package/dist/stores/file-store.js +284 -0
- package/dist/stores/file-store.js.map +1 -0
- package/dist/stores/provider-store.d.ts +24 -0
- package/dist/stores/provider-store.d.ts.map +1 -0
- package/dist/stores/provider-store.js +56 -0
- package/dist/stores/provider-store.js.map +1 -0
- package/dist/stores/ui-store.d.ts +21 -0
- package/dist/stores/ui-store.d.ts.map +1 -0
- package/dist/stores/ui-store.js +23 -0
- package/dist/stores/ui-store.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/voice/asr-clients.d.ts +2 -0
- package/dist/voice/asr-clients.d.ts.map +1 -0
- package/dist/voice/asr-clients.js +33 -0
- package/dist/voice/asr-clients.js.map +1 -0
- package/dist/voice/asr-deepgram.d.ts +38 -0
- package/dist/voice/asr-deepgram.d.ts.map +1 -0
- package/dist/voice/asr-deepgram.js +307 -0
- package/dist/voice/asr-deepgram.js.map +1 -0
- package/dist/voice/asr-webspeech.d.ts +23 -0
- package/dist/voice/asr-webspeech.d.ts.map +1 -0
- package/dist/voice/asr-webspeech.js +93 -0
- package/dist/voice/asr-webspeech.js.map +1 -0
- package/dist/voice/use-dictation.d.ts +6 -0
- package/dist/voice/use-dictation.d.ts.map +1 -0
- package/dist/voice/use-dictation.js +174 -0
- package/dist/voice/use-dictation.js.map +1 -0
- package/dist/voice/voice-store.d.ts +26 -0
- package/dist/voice/voice-store.d.ts.map +1 -0
- package/dist/voice/voice-store.js +27 -0
- package/dist/voice/voice-store.js.map +1 -0
- package/package.json +71 -0
- package/src/components/chat/ask-user-card.tsx +451 -0
- package/src/components/chat/brain-markdown.tsx +547 -0
- package/src/components/chat/chat-page.tsx +820 -0
- package/src/components/chat/command-palette.tsx +68 -0
- package/src/components/chat/markdown-content.tsx +5 -0
- package/src/components/chat/message-bubble.tsx +362 -0
- package/src/components/chat/message-share.ts +78 -0
- package/src/components/chat/renderers/claude-tools.tsx +53 -0
- package/src/components/chat/renderers/generic.tsx +85 -0
- package/src/components/chat/renderers/index.ts +19 -0
- package/src/components/chat/risk-hints.ts +95 -0
- package/src/components/chat/session-drawer.tsx +213 -0
- package/src/components/chat/share-block.tsx +128 -0
- package/src/components/chat/tool-call-timeline.tsx +322 -0
- package/src/components/chat/tool-views.tsx +898 -0
- package/src/components/chat/welcome-state.tsx +105 -0
- package/src/components/connectivity/connection-gate.tsx +137 -0
- package/src/components/connectivity/login-screen.tsx +169 -0
- package/src/components/files/file-panel.tsx +116 -0
- package/src/components/files/file-tree.tsx +143 -0
- package/src/components/files/file-viewer-binary.tsx +63 -0
- package/src/components/files/file-viewer-html.tsx +10 -0
- package/src/components/files/file-viewer-markdown.tsx +14 -0
- package/src/components/files/file-viewer-raw.tsx +44 -0
- package/src/components/files/file-viewer.tsx +290 -0
- package/src/components/files/frontmatter-panel.tsx +78 -0
- package/src/components/layout/app-shell.tsx +25 -0
- package/src/components/layout/mobile-tab-bar.tsx +54 -0
- package/src/components/layout/side-rail.tsx +128 -0
- package/src/components/layout/slide-panel.tsx +64 -0
- package/src/components/quick-actions/streaming-modal.tsx +168 -0
- package/src/components/quick-actions/whatsup-modal.tsx +149 -0
- package/src/components/settings/passkey-panel.tsx +281 -0
- package/src/components/share/share-menu.tsx +121 -0
- package/src/components/voice/dictation-sheet.tsx +217 -0
- package/src/components/voice/mic-button.tsx +31 -0
- package/src/components/voice/review-card.tsx +66 -0
- package/src/config.ts +27 -0
- package/src/hooks/use-vpn-status.ts +75 -0
- package/src/hooks/use-websocket.ts +403 -0
- package/src/index.ts +46 -0
- package/src/lib/api-client.ts +173 -0
- package/src/lib/backend.ts +35 -0
- package/src/lib/frontmatter.ts +99 -0
- package/src/lib/image-attachments.ts +221 -0
- package/src/lib/passkeys.ts +50 -0
- package/src/lib/share.ts +167 -0
- package/src/lib/strip-markdown.ts +38 -0
- package/src/lib/tool-names.ts +27 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/ws-client.ts +109 -0
- package/src/stores/chat-store.ts +619 -0
- package/src/stores/connection-store.ts +23 -0
- package/src/stores/file-store.ts +344 -0
- package/src/stores/provider-store.ts +85 -0
- package/src/stores/ui-store.ts +48 -0
- package/src/styles.css +4 -0
- package/src/theme.css +425 -0
- package/src/voice/asr-clients.ts +45 -0
- package/src/voice/asr-deepgram.ts +325 -0
- package/src/voice/asr-webspeech.ts +135 -0
- package/src/voice/use-dictation.ts +187 -0
- package/src/voice/voice-store.ts +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-panel.d.ts","sourceRoot":"","sources":["../../../src/components/settings/passkey-panel.tsx"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,+BAyJA"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Check, Cloud, Fingerprint, Loader2, LogOut, Pencil, Plus, Trash2, X, } from "lucide-react";
|
|
4
|
+
import { api } from "../../lib/api-client.js";
|
|
5
|
+
import { isUserCancel, registerPasskey, supportsPasskeys } from "../../lib/passkeys.js";
|
|
6
|
+
import { SlidePanel } from "../layout/slide-panel.js";
|
|
7
|
+
import { cn } from "../../lib/utils.js";
|
|
8
|
+
/**
|
|
9
|
+
* Passkey management + sign out. Registration requires the current session
|
|
10
|
+
* (routes are behind the auth guard); credentials are RP-scoped, so entries
|
|
11
|
+
* registered on another hostname are badged and only useful there.
|
|
12
|
+
*/
|
|
13
|
+
export function PasskeyPanel({ open, onClose, }) {
|
|
14
|
+
const [credentials, setCredentials] = useState([]);
|
|
15
|
+
const [loading, setLoading] = useState(false);
|
|
16
|
+
const [busy, setBusy] = useState(false);
|
|
17
|
+
const [error, setError] = useState(null);
|
|
18
|
+
const [passkeyMode, setPasskeyMode] = useState(true);
|
|
19
|
+
const webAuthnSupported = supportsPasskeys();
|
|
20
|
+
async function refresh() {
|
|
21
|
+
setLoading(true);
|
|
22
|
+
try {
|
|
23
|
+
const data = await api.passkeyList();
|
|
24
|
+
setCredentials(data.credentials);
|
|
25
|
+
setPasskeyMode(true);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// 400 = server not in password mode; anything else degrades the same way.
|
|
29
|
+
setPasskeyMode(false);
|
|
30
|
+
setCredentials([]);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
setLoading(false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (open) {
|
|
38
|
+
setError(null);
|
|
39
|
+
void refresh();
|
|
40
|
+
}
|
|
41
|
+
}, [open]);
|
|
42
|
+
async function onAdd() {
|
|
43
|
+
if (busy)
|
|
44
|
+
return;
|
|
45
|
+
setBusy(true);
|
|
46
|
+
setError(null);
|
|
47
|
+
try {
|
|
48
|
+
await registerPasskey();
|
|
49
|
+
await refresh();
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
if (!isUserCancel(err)) {
|
|
53
|
+
setError(err instanceof Error ? err.message : "Registration failed");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
setBusy(false);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function onDelete(id) {
|
|
61
|
+
if (!window.confirm("Remove this passkey? You can't undo this."))
|
|
62
|
+
return;
|
|
63
|
+
setError(null);
|
|
64
|
+
try {
|
|
65
|
+
await api.passkeyDelete(id);
|
|
66
|
+
setCredentials((rows) => rows.filter((row) => row.id !== id));
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
setError(err instanceof Error ? err.message : "Delete failed");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function onRename(id, label) {
|
|
73
|
+
setError(null);
|
|
74
|
+
try {
|
|
75
|
+
await api.passkeyRename(id, label);
|
|
76
|
+
setCredentials((rows) => rows.map((row) => (row.id === id ? { ...row, label } : row)));
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
setError(err instanceof Error ? err.message : "Rename failed");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function onSignOut() {
|
|
83
|
+
try {
|
|
84
|
+
await api.logout();
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
window.location.reload();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return (_jsx(SlidePanel, { open: open, onClose: onClose, title: "Security", children: _jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex-1 overflow-y-auto p-4", children: [_jsx("h3", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Passkeys" }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Sign in with Face ID, fingerprint, or a security key instead of the password. Passkeys only work on the site they were added on." }), loading ? (_jsx("div", { className: "mt-6 flex justify-center", children: _jsx(Loader2, { className: "h-5 w-5 animate-spin text-muted-foreground" }) })) : (_jsxs("ul", { className: "mt-4 flex flex-col gap-2", children: [credentials.map((credential) => (_jsx(PasskeyRow, { credential: credential, onDelete: () => onDelete(credential.id), onRename: (label) => onRename(credential.id, label) }, credential.id))), credentials.length === 0 && passkeyMode && (_jsx("li", { className: "rounded-lg border border-dashed border-border-subtle p-4 text-center text-xs text-muted-foreground", children: "No passkeys yet." }))] })), error && (_jsx("p", { role: "alert", className: "mt-3 text-xs text-destructive", children: error })), passkeyMode && webAuthnSupported ? (_jsxs("button", { onClick: onAdd, disabled: busy, className: "mt-4 flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:brightness-110 disabled:opacity-50", children: [busy ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Plus, { className: "h-4 w-4" })), "Add a passkey"] })) : (_jsx("p", { className: "mt-4 text-xs text-muted-foreground", children: passkeyMode
|
|
91
|
+
? "This browser does not support passkeys."
|
|
92
|
+
: "Passkeys need password auth mode on the server." }))] }), _jsx("div", { className: "border-t border-border p-4", children: _jsxs("button", { onClick: onSignOut, className: "flex w-full items-center justify-center gap-2 rounded-lg border border-border-subtle bg-surface px-4 py-2 text-sm font-medium text-foreground transition-colors hover:border-destructive hover:text-destructive", children: [_jsx(LogOut, { className: "h-4 w-4" }), "Sign out"] }) })] }) }));
|
|
93
|
+
}
|
|
94
|
+
function PasskeyRow({ credential, onDelete, onRename, }) {
|
|
95
|
+
const [editing, setEditing] = useState(false);
|
|
96
|
+
const [draft, setDraft] = useState(credential.label);
|
|
97
|
+
const foreignRp = typeof window !== "undefined" && credential.rpId !== window.location.hostname;
|
|
98
|
+
const displayName = credential.label ||
|
|
99
|
+
`Passkey · ${new Date(credential.createdAt).toLocaleDateString()}`;
|
|
100
|
+
function commit() {
|
|
101
|
+
setEditing(false);
|
|
102
|
+
const label = draft.trim();
|
|
103
|
+
if (label !== credential.label)
|
|
104
|
+
onRename(label);
|
|
105
|
+
}
|
|
106
|
+
return (_jsxs("li", { className: "rounded-lg border border-border-subtle bg-surface p-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Fingerprint, { className: "h-4 w-4 shrink-0 text-primary" }), editing ? (_jsxs("span", { className: "flex flex-1 items-center gap-1", children: [_jsx("input", { autoFocus: true, value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
|
|
107
|
+
if (e.key === "Enter")
|
|
108
|
+
commit();
|
|
109
|
+
if (e.key === "Escape")
|
|
110
|
+
setEditing(false);
|
|
111
|
+
}, className: "w-full rounded border border-border-subtle bg-background px-2 py-0.5 text-sm text-foreground outline-none focus:border-primary" }), _jsx("button", { onClick: commit, title: "Save", className: "p-1 text-muted-foreground hover:text-foreground", children: _jsx(Check, { className: "h-3.5 w-3.5" }) }), _jsx("button", { onClick: () => setEditing(false), title: "Cancel", className: "p-1 text-muted-foreground hover:text-foreground", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] })) : (_jsx("span", { className: "flex-1 truncate text-sm text-foreground", children: displayName })), !editing && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => {
|
|
112
|
+
setDraft(credential.label);
|
|
113
|
+
setEditing(true);
|
|
114
|
+
}, title: "Rename", className: "p-1 text-muted-foreground transition-colors hover:text-foreground", children: _jsx(Pencil, { className: "h-3.5 w-3.5" }) }), _jsx("button", { onClick: onDelete, title: "Remove", className: "p-1 text-muted-foreground transition-colors hover:text-destructive", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] }))] }), _jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 pl-6 text-[11px] text-muted-foreground", children: [credential.backedUp && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Cloud, { className: "h-3 w-3" }), " Synced"] })), foreignRp && (_jsx("span", { className: cn("rounded bg-surface-raised px-1.5 py-0.5 font-medium text-foreground/70"), title: `Registered on ${credential.rpId}; only usable there.`, children: credential.rpId })), _jsx("span", { children: credential.lastUsedAt
|
|
115
|
+
? `Last used ${new Date(credential.lastUsedAt).toLocaleDateString()}`
|
|
116
|
+
: `Added ${new Date(credential.createdAt).toLocaleDateString()}` })] })] }));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=passkey-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-panel.js","sourceRoot":"","sources":["../../../src/components/settings/passkey-panel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface ShareOption {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
/** Optional short hint shown below the label. */
|
|
5
|
+
hint?: string;
|
|
6
|
+
/** Async action: returns true on success, false on user-cancel. */
|
|
7
|
+
run: () => Promise<boolean>;
|
|
8
|
+
}
|
|
9
|
+
interface ShareMenuProps {
|
|
10
|
+
options: ShareOption[];
|
|
11
|
+
/** Aria label / tooltip for the trigger button. */
|
|
12
|
+
title?: string;
|
|
13
|
+
/** When provided, override the default icon button with a custom trigger. */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Optional render-prop for a custom trigger; receives the click handler. */
|
|
16
|
+
renderTrigger?: (props: {
|
|
17
|
+
onClick: () => void;
|
|
18
|
+
busy: boolean;
|
|
19
|
+
}) => React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
export declare function ShareMenu({ options, title, className, renderTrigger }: ShareMenuProps): import("react").JSX.Element;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=share-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-menu.d.ts","sourceRoot":"","sources":["../../../src/components/share/share-menu.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAC;CACpF;AAID,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,KAAe,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,cAAc,+BA+F/F"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { Share2, Loader2, Check, AlertCircle } from "lucide-react";
|
|
4
|
+
import { cn } from "../../lib/utils.js";
|
|
5
|
+
export function ShareMenu({ options, title = "Share", className, renderTrigger }) {
|
|
6
|
+
const [open, setOpen] = useState(false);
|
|
7
|
+
const [status, setStatus] = useState("idle");
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const wrapperRef = useRef(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!open)
|
|
12
|
+
return;
|
|
13
|
+
const onDocClick = (e) => {
|
|
14
|
+
if (!wrapperRef.current?.contains(e.target))
|
|
15
|
+
setOpen(false);
|
|
16
|
+
};
|
|
17
|
+
const onKey = (e) => {
|
|
18
|
+
if (e.key === "Escape")
|
|
19
|
+
setOpen(false);
|
|
20
|
+
};
|
|
21
|
+
document.addEventListener("mousedown", onDocClick);
|
|
22
|
+
document.addEventListener("keydown", onKey);
|
|
23
|
+
return () => {
|
|
24
|
+
document.removeEventListener("mousedown", onDocClick);
|
|
25
|
+
document.removeEventListener("keydown", onKey);
|
|
26
|
+
};
|
|
27
|
+
}, [open]);
|
|
28
|
+
// If there's only one option, the trigger should fire it directly.
|
|
29
|
+
const single = options.length === 1 ? options[0] : null;
|
|
30
|
+
const runOption = async (opt) => {
|
|
31
|
+
setOpen(false);
|
|
32
|
+
setStatus("busy");
|
|
33
|
+
setError(null);
|
|
34
|
+
try {
|
|
35
|
+
await opt.run();
|
|
36
|
+
setStatus("done");
|
|
37
|
+
setTimeout(() => setStatus("idle"), 1200);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error("[share-menu]", err);
|
|
41
|
+
setError(err instanceof Error ? err.message : "Share failed");
|
|
42
|
+
setStatus("error");
|
|
43
|
+
setTimeout(() => setStatus("idle"), 3000);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const handleTrigger = () => {
|
|
47
|
+
if (status === "busy")
|
|
48
|
+
return;
|
|
49
|
+
if (single) {
|
|
50
|
+
void runOption(single);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
setOpen((v) => !v);
|
|
54
|
+
};
|
|
55
|
+
const icon = status === "busy" ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : status === "done" ? (_jsx(Check, { className: "h-3.5 w-3.5" })) : status === "error" ? (_jsx(AlertCircle, { className: "h-3.5 w-3.5 text-destructive" })) : (_jsx(Share2, { className: "h-3.5 w-3.5" }));
|
|
56
|
+
return (_jsxs("div", { ref: wrapperRef, className: cn("relative inline-flex", className), children: [renderTrigger ? (renderTrigger({ onClick: handleTrigger, busy: status === "busy" })) : (_jsx("button", { onClick: handleTrigger, disabled: status === "busy", title: error ?? title, className: "rounded p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground disabled:opacity-50", children: icon })), open && !single && (_jsx("div", { role: "menu", className: "absolute right-0 top-full z-50 mt-1 min-w-[12rem] overflow-hidden rounded-lg border border-border bg-background py-1 shadow-lg", children: options.map((opt) => (_jsxs("button", { role: "menuitem", onClick: () => void runOption(opt), className: "block w-full px-3 py-2 text-left text-xs text-foreground transition-colors hover:bg-surface-raised", children: [_jsx("div", { className: "font-medium", children: opt.label }), opt.hint && _jsx("div", { className: "text-[10px] text-muted-foreground", children: opt.hint })] }, opt.id))) }))] }));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=share-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-menu.js","sourceRoot":"","sources":["../../../src/components/share/share-menu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAuBxC,MAAM,UAAU,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE,SAAS,EAAE,aAAa,EAAkB;IAC9F,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAS,MAAM,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,UAAU,GAAG,CAAC,CAAa,EAAE,EAAE;YACnC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAc,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACtE,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAE,EAAE;YACjC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACnD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YACtD,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,mEAAmE;IACnE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAExD,MAAM,SAAS,GAAG,KAAK,EAAE,GAAgB,EAAE,EAAE;QAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;YAChB,SAAS,CAAC,MAAM,CAAC,CAAC;YAClB,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACnC,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YAC9D,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,SAAS,CAAC,MAAM,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QACD,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,IAAI,GACR,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAClB,KAAC,OAAO,IAAC,SAAS,EAAC,0BAA0B,GAAG,CACjD,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CACtB,KAAC,KAAK,IAAC,SAAS,EAAC,aAAa,GAAG,CAClC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CACvB,KAAC,WAAW,IAAC,SAAS,EAAC,8BAA8B,GAAG,CACzD,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IAAC,SAAS,EAAC,aAAa,GAAG,CACnC,CAAC;IAEJ,OAAO,CACL,eAAK,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC,sBAAsB,EAAE,SAAS,CAAC,aACnE,aAAa,CAAC,CAAC,CAAC,CACf,aAAa,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC,CACnE,CAAC,CAAC,CAAC,CACF,iBACE,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,KAAK,MAAM,EAC3B,KAAK,EAAE,KAAK,IAAI,KAAK,EACrB,SAAS,EAAC,yHAAyH,YAElI,IAAI,GACE,CACV,EACA,IAAI,IAAI,CAAC,MAAM,IAAI,CAClB,cACE,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,gIAAgI,YAEzI,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,kBAEE,IAAI,EAAC,UAAU,EACf,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,GAAG,CAAC,EAClC,SAAS,EAAC,oGAAoG,aAE9G,cAAK,SAAS,EAAC,aAAa,YAAE,GAAG,CAAC,KAAK,GAAO,EAC7C,GAAG,CAAC,IAAI,IAAI,cAAK,SAAS,EAAC,mCAAmC,YAAE,GAAG,CAAC,IAAI,GAAO,KAN3E,GAAG,CAAC,EAAE,CAOJ,CACV,CAAC,GACE,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dictation-sheet.d.ts","sourceRoot":"","sources":["../../../src/components/voice/dictation-sheet.tsx"],"names":[],"mappings":"AAKA,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,sCAqKA"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { Mic, X } from "lucide-react";
|
|
4
|
+
import { useVoiceStore } from "../../voice/voice-store.js";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
export function DictationSheet({ open, onStop, onCancel, }) {
|
|
7
|
+
const partial = useVoiceStore((s) => s.partial);
|
|
8
|
+
const finalText = useVoiceStore((s) => s.finalText);
|
|
9
|
+
const audioLevel = useVoiceStore((s) => s.audioLevel);
|
|
10
|
+
const error = useVoiceStore((s) => s.error);
|
|
11
|
+
const draining = useVoiceStore((s) => s.draining);
|
|
12
|
+
// Mic still opening — the session is being fetched, so capture isn't live
|
|
13
|
+
// yet. Drives the honest "Connecting…" state instead of claiming "Listening".
|
|
14
|
+
const connecting = useVoiceStore((s) => s.connecting);
|
|
15
|
+
const providerId = useVoiceStore((s) => s.providerId);
|
|
16
|
+
// Text already under review — the current capture appends to it on stop,
|
|
17
|
+
// so show it dimmed as the lead-in.
|
|
18
|
+
const reviewText = useVoiceStore((s) => s.reviewText);
|
|
19
|
+
const transcriptRef = useRef(null);
|
|
20
|
+
const statusLabel = connecting
|
|
21
|
+
? "Connecting…"
|
|
22
|
+
: draining
|
|
23
|
+
? "Finalizing…"
|
|
24
|
+
: "Listening";
|
|
25
|
+
// Surface the active provider so a silent fallback to browser speech (which
|
|
26
|
+
// streams mic audio to Google on Chrome) isn't invisible.
|
|
27
|
+
const providerNote = providerNoteFor(providerId);
|
|
28
|
+
// Keep the newest words in view — the live transcript grows past the
|
|
29
|
+
// sheet's height quickly when dictating longer prompts.
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const el = transcriptRef.current;
|
|
32
|
+
if (el)
|
|
33
|
+
el.scrollTop = el.scrollHeight;
|
|
34
|
+
}, [finalText, partial, open]);
|
|
35
|
+
// Lock body scroll while open
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!open)
|
|
38
|
+
return;
|
|
39
|
+
const prev = document.body.style.overflow;
|
|
40
|
+
document.body.style.overflow = "hidden";
|
|
41
|
+
return () => {
|
|
42
|
+
document.body.style.overflow = prev;
|
|
43
|
+
};
|
|
44
|
+
}, [open]);
|
|
45
|
+
// Escape cancels
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!open)
|
|
48
|
+
return;
|
|
49
|
+
const h = (e) => {
|
|
50
|
+
if (e.key === "Escape")
|
|
51
|
+
onCancel();
|
|
52
|
+
};
|
|
53
|
+
document.addEventListener("keydown", h);
|
|
54
|
+
return () => document.removeEventListener("keydown", h);
|
|
55
|
+
}, [open, onCancel]);
|
|
56
|
+
if (!open)
|
|
57
|
+
return null;
|
|
58
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/60 backdrop-blur-sm", onClick: () => { if (!draining)
|
|
59
|
+
onStop(); } }), _jsxs("div", { className: cn("fixed inset-x-0 bottom-0 z-50 flex flex-col rounded-t-3xl border-t border-border bg-surface shadow-[0_-16px_48px_rgba(0,0,0,0.5)]", "max-h-[60vh] min-h-[40vh]", "animate-in slide-in-from-bottom duration-200"),
|
|
60
|
+
// Don't propagate to backdrop
|
|
61
|
+
onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border/50 px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "relative inline-flex h-2 w-2", children: [!connecting && (_jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75" })), _jsx("span", { className: cn("relative inline-flex h-2 w-2 rounded-full", connecting ? "bg-muted-foreground/50" : "bg-primary") })] }), _jsx("span", { className: "font-[family-name:var(--font-mono)] text-xs uppercase tracking-widest text-muted-foreground", children: statusLabel })] }), _jsx("button", { onClick: onCancel, disabled: draining, title: "Cancel", className: "rounded-lg p-2 text-muted-foreground hover:bg-surface-raised hover:text-foreground disabled:opacity-30", children: _jsx(X, { className: "h-4 w-4" }) })] }), providerNote && !error && (_jsx("div", { className: cn("px-5 pt-2 text-center text-[11px]", providerNote.warn
|
|
62
|
+
? "text-primary/90"
|
|
63
|
+
: "text-muted-foreground/50"), children: providerNote.text })), _jsx("div", { className: "flex items-center justify-center px-6 py-4", children: _jsx(Waveform, { level: audioLevel }) }), _jsx("div", { ref: transcriptRef, className: "flex-1 overflow-y-auto px-6 pb-6", children: error ? (_jsx("div", { className: "rounded-lg bg-destructive/10 p-4 text-sm text-destructive", children: error })) : (_jsxs("p", { className: "text-base leading-relaxed", children: [reviewText && (_jsxs("span", { className: "text-muted-foreground/50", children: [reviewText, " "] })), _jsx("span", { className: "text-foreground", children: finalText }), finalText && partial && " ", _jsx("span", { className: "text-muted-foreground/60", children: partial }), !reviewText && !finalText && !partial && (_jsx("span", { className: "text-muted-foreground/40", children: "Speak to start..." }))] })) }), _jsxs("div", { className: "border-t border-border/50 p-4", children: [_jsxs("button", { onClick: onStop, disabled: draining, className: "flex h-14 w-full items-center justify-center gap-3 rounded-xl bg-primary text-primary-foreground transition-all duration-150 hover:brightness-110 active:scale-[0.99] disabled:opacity-60 disabled:cursor-progress", children: [_jsx(Mic, { className: "h-5 w-5" }), _jsx("span", { className: "text-sm font-semibold uppercase tracking-wider", children: draining ? "Finalizing…" : "Done" })] }), _jsx("p", { className: "mt-2 text-center text-[11px] text-muted-foreground/50", children: draining
|
|
64
|
+
? "Waiting for the last words…"
|
|
65
|
+
: "Tap anywhere outside to stop" })] })] })] }));
|
|
66
|
+
}
|
|
67
|
+
/** Human-readable note for the active speech provider, or null if unknown. */
|
|
68
|
+
function providerNoteFor(providerId) {
|
|
69
|
+
switch (providerId) {
|
|
70
|
+
case "deepgram":
|
|
71
|
+
return { text: "via Deepgram", warn: false };
|
|
72
|
+
case "webspeech":
|
|
73
|
+
// Browser speech (Chrome) streams mic audio to Google — call it out.
|
|
74
|
+
return { text: "via browser speech · audio goes to Google", warn: true };
|
|
75
|
+
case null:
|
|
76
|
+
return null;
|
|
77
|
+
default:
|
|
78
|
+
return { text: `via ${providerId}`, warn: false };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function Waveform({ level }) {
|
|
82
|
+
// Render 16 bars whose height is driven by current level + per-bar phase.
|
|
83
|
+
const bars = 16;
|
|
84
|
+
return (_jsx("div", { className: "flex h-16 items-center gap-1.5", children: Array.from({ length: bars }).map((_, i) => {
|
|
85
|
+
const phase = (i / bars) * Math.PI;
|
|
86
|
+
const offset = (Math.sin(phase + Date.now() / 200) + 1) / 2;
|
|
87
|
+
const h = 8 + level * 56 * (0.4 + 0.6 * offset);
|
|
88
|
+
return (_jsx("span", { style: { height: `${h}px` }, className: "w-1.5 rounded-full bg-primary transition-[height] duration-75 ease-linear" }, i));
|
|
89
|
+
}) }));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=dictation-sheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dictation-sheet.js","sourceRoot":"","sources":["../../../src/components/voice/dictation-sheet.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mic-button.d.ts","sourceRoot":"","sources":["../../../src/components/voice/mic-button.tsx"],"names":[],"mappings":"AAGA,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,QAAQ,EACR,KAAK,GACN,EAAE;IACD,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,+BAmBA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Mic } from "lucide-react";
|
|
3
|
+
import { cn } from "../../lib/utils.js";
|
|
4
|
+
export function MicButton({ active, disabled, onTap, }) {
|
|
5
|
+
return (_jsx("button", { type: "button", onClick: onTap, disabled: disabled, title: active ? "Stop dictation" : "Voice dictation", "aria-label": active ? "Stop dictation" : "Voice dictation", className: cn("flex h-8 w-8 items-center justify-center rounded-lg transition-all duration-150", active
|
|
6
|
+
? "bg-primary text-primary-foreground animate-pulse"
|
|
7
|
+
: "text-muted-foreground hover:bg-surface-raised hover:text-foreground", disabled && "opacity-30 cursor-not-allowed"), children: _jsx(Mic, { className: "h-4 w-4" }) }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=mic-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mic-button.js","sourceRoot":"","sources":["../../../src/components/voice/mic-button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAExC,MAAM,UAAU,SAAS,CAAC,EACxB,MAAM,EACN,QAAQ,EACR,KAAK,GAKN;IACC,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,KAAK,EACd,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,gBACxC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,EACzD,SAAS,EAAE,EAAE,CACX,iFAAiF,EACjF,MAAM;YACJ,CAAC,CAAC,kDAAkD;YACpD,CAAC,CAAC,qEAAqE,EACzE,QAAQ,IAAI,+BAA+B,CAC5C,YAED,KAAC,GAAG,IAAC,SAAS,EAAC,SAAS,GAAG,GACpB,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function ReviewCard({ text, onSend, onEdit, onDiscard, onAppend, }: {
|
|
2
|
+
text: string;
|
|
3
|
+
onSend: () => void;
|
|
4
|
+
onEdit: () => void;
|
|
5
|
+
onDiscard: () => void;
|
|
6
|
+
onAppend: () => void;
|
|
7
|
+
}): import("react").JSX.Element | null;
|
|
8
|
+
//# sourceMappingURL=review-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-card.d.ts","sourceRoot":"","sources":["../../../src/components/voice/review-card.tsx"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,sCAmDA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Mic, Pencil, Send, X } from "lucide-react";
|
|
3
|
+
export function ReviewCard({ text, onSend, onEdit, onDiscard, onAppend, }) {
|
|
4
|
+
if (!text)
|
|
5
|
+
return null;
|
|
6
|
+
return (_jsxs("div", { className: "mb-2 rounded-2xl border border-primary/30 bg-surface shadow-[0_8px_24px_rgba(0,0,0,0.3)]", children: [_jsxs("div", { className: "flex items-start gap-3 px-4 pt-3 pb-2", children: [_jsx(Mic, { className: "mt-0.5 h-4 w-4 flex-none text-primary" }), _jsx("p", { className: "max-h-40 flex-1 overflow-y-auto text-sm leading-relaxed text-foreground", children: text })] }), _jsxs("div", { className: "flex items-center justify-between border-t border-border/40 px-2 py-2", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsxs("button", { type: "button", onClick: onDiscard, title: "Discard", className: "flex h-9 items-center gap-1.5 rounded-lg px-3 text-xs text-muted-foreground transition-colors hover:bg-surface-raised hover:text-destructive", children: [_jsx(X, { className: "h-3.5 w-3.5" }), "Discard"] }), _jsxs("button", { type: "button", onClick: onEdit, title: "Edit", className: "flex h-9 items-center gap-1.5 rounded-lg px-3 text-xs text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground", children: [_jsx(Pencil, { className: "h-3.5 w-3.5" }), "Edit"] }), _jsxs("button", { type: "button", onClick: onAppend, title: "Append more voice", className: "flex h-9 items-center gap-1.5 rounded-lg px-3 text-xs text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground", children: [_jsx(Mic, { className: "h-3.5 w-3.5" }), "Add"] })] }), _jsxs("button", { type: "button", onClick: onSend, className: "flex h-10 items-center gap-2 rounded-xl bg-primary px-5 text-sm font-semibold text-primary-foreground transition-all duration-150 hover:brightness-110 active:scale-[0.98]", children: [_jsx(Send, { className: "h-4 w-4" }), "Send"] })] })] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=review-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-card.js","sourceRoot":"","sources":["../../../src/components/voice/review-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,UAAU,UAAU,CAAC,EACzB,IAAI,EACJ,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,GAOT;IACC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,CACL,eAAK,SAAS,EAAC,0FAA0F,aACvG,eAAK,SAAS,EAAC,uCAAuC,aACpD,KAAC,GAAG,IAAC,SAAS,EAAC,uCAAuC,GAAG,EACzD,YAAG,SAAS,EAAC,yEAAyE,YACnF,IAAI,GACH,IACA,EACN,eAAK,SAAS,EAAC,uEAAuE,aACpF,eAAK,SAAS,EAAC,yBAAyB,aACtC,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,SAAS,EAClB,KAAK,EAAC,SAAS,EACf,SAAS,EAAC,8IAA8I,aAExJ,KAAC,CAAC,IAAC,SAAS,EAAC,aAAa,GAAG,eAEtB,EACT,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAC,MAAM,EACZ,SAAS,EAAC,6IAA6I,aAEvJ,KAAC,MAAM,IAAC,SAAS,EAAC,aAAa,GAAG,YAE3B,EACT,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAC,mBAAmB,EACzB,SAAS,EAAC,6IAA6I,aAEvJ,KAAC,GAAG,IAAC,SAAS,EAAC,aAAa,GAAG,WAExB,IACL,EACN,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAC,4KAA4K,aAEtL,KAAC,IAAI,IAAC,SAAS,EAAC,SAAS,GAAG,YAErB,IACL,IACF,CACP,CAAC;AACJ,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment-tunable branding/copy. A module-level singleton, matching the
|
|
3
|
+
* renderer/ASR registries: the shell calls `configureBrainUi()` once at boot
|
|
4
|
+
* (before mounting), components read `uiConfig` at render time. Runtime
|
|
5
|
+
* plugin-style reconfiguration is deliberately unsupported.
|
|
6
|
+
*/
|
|
7
|
+
export interface BrainUiConfig {
|
|
8
|
+
/** Product name shown on the login screen and connection status. */
|
|
9
|
+
appName: string;
|
|
10
|
+
/** Name the assistant speaks as in the transcript. */
|
|
11
|
+
assistantName: string;
|
|
12
|
+
/** Default title for shared artifacts (share cards, rendered PNG/PDF). */
|
|
13
|
+
shareTitle: string;
|
|
14
|
+
/** Composer placeholder. */
|
|
15
|
+
composerPlaceholder: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const uiConfig: BrainUiConfig;
|
|
18
|
+
export declare function configureBrainUi(overrides: Partial<BrainUiConfig>): void;
|
|
19
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,QAAQ,EAAE,aAKtB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAExE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const uiConfig = {
|
|
2
|
+
appName: "Brain UI",
|
|
3
|
+
assistantName: "Brain",
|
|
4
|
+
shareTitle: "Shared from Brain",
|
|
5
|
+
composerPlaceholder: "Ask your brain anything...",
|
|
6
|
+
};
|
|
7
|
+
export function configureBrainUi(overrides) {
|
|
8
|
+
Object.assign(uiConfig, overrides);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,MAAM,QAAQ,GAAkB;IACrC,OAAO,EAAE,UAAU;IACnB,aAAa,EAAE,OAAO;IACtB,UAAU,EAAE,mBAAmB;IAC/B,mBAAmB,EAAE,4BAA4B;CAClD,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,SAAiC;IAChE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-vpn-status.d.ts","sourceRoot":"","sources":["../../src/hooks/use-vpn-status.ts"],"names":[],"mappings":"AASA,wBAAgB,YAAY,SAiE3B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useConnectionStore } from "../stores/connection-store.js";
|
|
3
|
+
import { getBackendUrl } from "../lib/backend.js";
|
|
4
|
+
const POLL_INTERVAL = 15_000;
|
|
5
|
+
// Tighter cadence while offline so recovery is near-immediate
|
|
6
|
+
const OFFLINE_POLL_INTERVAL = 3_000;
|
|
7
|
+
const TIMEOUT_MS = 5_000;
|
|
8
|
+
export function useVpnStatus() {
|
|
9
|
+
const setVpnStatus = useConnectionStore((s) => s.setVpnStatus);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
let timer;
|
|
12
|
+
let inFlight = false;
|
|
13
|
+
let disposed = false;
|
|
14
|
+
async function check() {
|
|
15
|
+
if (inFlight || disposed)
|
|
16
|
+
return;
|
|
17
|
+
inFlight = true;
|
|
18
|
+
let connected = false;
|
|
19
|
+
try {
|
|
20
|
+
const controller = new AbortController();
|
|
21
|
+
const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
22
|
+
const res = await fetch(getBackendUrl("/api/vpn-check"), {
|
|
23
|
+
signal: controller.signal,
|
|
24
|
+
});
|
|
25
|
+
clearTimeout(timeout);
|
|
26
|
+
if (res.ok) {
|
|
27
|
+
setVpnStatus("connected");
|
|
28
|
+
connected = true;
|
|
29
|
+
}
|
|
30
|
+
else if (res.status === 401) {
|
|
31
|
+
// Auth required (password / proxy mode) but no valid session yet.
|
|
32
|
+
setVpnStatus("unauthorized");
|
|
33
|
+
connected = true; // reachable — poll at the relaxed cadence
|
|
34
|
+
}
|
|
35
|
+
else if (res.status === 403) {
|
|
36
|
+
setVpnStatus("forbidden");
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
setVpnStatus("unreachable");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
setVpnStatus("unreachable");
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
inFlight = false;
|
|
47
|
+
if (!disposed) {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
timer = setTimeout(check, connected ? POLL_INTERVAL : OFFLINE_POLL_INTERVAL);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Re-check immediately when the network returns or the PWA is foregrounded
|
|
54
|
+
// instead of waiting out the poll interval.
|
|
55
|
+
const recheckNow = () => void check();
|
|
56
|
+
const onVisible = () => {
|
|
57
|
+
if (document.visibilityState === "visible")
|
|
58
|
+
void check();
|
|
59
|
+
};
|
|
60
|
+
window.addEventListener("online", recheckNow);
|
|
61
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
62
|
+
void check();
|
|
63
|
+
return () => {
|
|
64
|
+
disposed = true;
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
window.removeEventListener("online", recheckNow);
|
|
67
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
68
|
+
};
|
|
69
|
+
}, [setVpnStatus]);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=use-vpn-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-vpn-status.js","sourceRoot":"","sources":["../../src/hooks/use-vpn-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ServerMessage, ClientMessage } from "@schlessera/brain-ui-sdk/protocol";
|
|
2
|
+
/** Map a frame to the run-state its session should show in the session list. */
|
|
3
|
+
export declare function runStateForFrame(msg: ServerMessage): "streaming" | "queued" | "idle";
|
|
4
|
+
export declare function handleServerMessage(msg: ServerMessage): void;
|
|
5
|
+
export declare function useWebSocket(): {
|
|
6
|
+
send: (msg: ClientMessage) => void;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=use-websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-websocket.d.ts","sourceRoot":"","sources":["../../src/hooks/use-websocket.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EAId,MAAM,mCAAmC,CAAC;AA2E3C,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAOpF;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,QAmKrD;AA8GD,wBAAgB,YAAY;gBA2BK,aAAa;EAK7C"}
|