SYMBOL INDEX (767 symbols across 91 files) FILE: app/main.js constant IS_E2E (line 25) | const IS_E2E = process.env.STENOAI_E2E === '1'; constant IS_E2E_MOCK_IPC (line 26) | const IS_E2E_MOCK_IPC = process.env.STENOAI_E2E_MOCK_IPC === '1'; constant SHORTCUT_PROTOCOL (line 46) | const SHORTCUT_PROTOCOL = 'stenoai'; constant SHORTCUT_HOST (line 47) | const SHORTCUT_HOST = 'record'; constant SHORTCUT_SESSION_NAME_MAX_LENGTH (line 48) | const SHORTCUT_SESSION_NAME_MAX_LENGTH = 120; function extractShortcutUrlFromArgv (line 51) | function extractShortcutUrlFromArgv(argv = []) { function sanitizeShortcutUrlForLogs (line 55) | function sanitizeShortcutUrlForLogs(incomingUrl) { function sanitizeShortcutSessionName (line 64) | function sanitizeShortcutSessionName(rawValue) { function registerShortcutProtocolClient (line 80) | function registerShortcutProtocolClient() { function getBackendPath (line 98) | function getBackendPath() { function getBackendCwd (line 108) | function getBackendCwd() { function parseShortcutUrl (line 116) | function parseShortcutUrl(incomingUrl) { function ensureMainWindow (line 146) | function ensureMainWindow() { function dispatchShortcutAction (line 159) | function dispatchShortcutAction(action) { function flushShortcutQueue (line 181) | function flushShortcutQueue() { function enqueueShortcutAction (line 196) | function enqueueShortcutAction(action) { function shouldShowShortcutNotifications (line 205) | async function shouldShowShortcutNotifications() { function showShortcutNotification (line 217) | async function showShortcutNotification(body) { constant BACKEND_STATUS_RETRY_ATTEMPTS (line 237) | const BACKEND_STATUS_RETRY_ATTEMPTS = 3; constant BACKEND_STATUS_RETRY_DELAY_MS (line 238) | const BACKEND_STATUS_RETRY_DELAY_MS = 250; function wait (line 240) | function wait(ms) { function isBackendRecording (line 244) | async function isBackendRecording() { function handleShortcutUrl (line 266) | async function handleShortcutUrl(incomingUrl) { constant POSTHOG_API_KEY (line 317) | const POSTHOG_API_KEY = 'phc_U2cnTyIyKGNSVaK18FyBMltd8nmN7uHxhhm21fAHwqb'; constant POSTHOG_HOST (line 318) | const POSTHOG_HOST = 'https://us.i.posthog.com'; constant GOOGLE_CLIENT_ID (line 321) | const GOOGLE_CLIENT_ID = '281073275073-20da4u5t9luk2366vd5ai0a2r55d5pf5.... constant GOOGLE_CLIENT_SECRET (line 322) | const GOOGLE_CLIENT_SECRET = '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'; constant GOOGLE_SCOPES (line 323) | const GOOGLE_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'; constant GOOGLE_AUTH_URL (line 324) | const GOOGLE_AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth'; constant GOOGLE_TOKEN_URL (line 325) | const GOOGLE_TOKEN_URL = 'https://oauth2.googleapis.com/token'; constant OUTLOOK_CLIENT_ID (line 328) | const OUTLOOK_CLIENT_ID = '53a8ba1f-3a2e-4fc9-afb1-b9b8ff13de19'; constant OUTLOOK_SCOPES (line 329) | const OUTLOOK_SCOPES = 'Calendars.Read offline_access'; constant OUTLOOK_AUTH_URL (line 330) | const OUTLOOK_AUTH_URL = 'https://login.microsoftonline.com/common/oauth... constant OUTLOOK_TOKEN_URL (line 331) | const OUTLOOK_TOKEN_URL = 'https://login.microsoftonline.com/common/oaut... function durationBucket (line 336) | function durationBucket(seconds) { function initTelemetry (line 348) | async function initTelemetry() { function trackEvent (line 394) | function trackEvent(eventName, properties = {}) { function shutdownTelemetry (line 419) | async function shutdownTelemetry() { function getAllowedBaseDirs (line 435) | function getAllowedBaseDirs() { function validateSafeFilePath (line 452) | function validateSafeFilePath(filepath, allowedBaseDirs) { function createWindow (line 474) | function createWindow(options = {}) { function getTrayIconPath (line 551) | function getTrayIconPath(recording) { function createTray (line 559) | function createTray() { function updateTrayIcon (line 568) | function updateTrayIcon(recording) { function showAndFocusWindow (line 577) | function showAndFocusWindow() { function updateTrayMenu (line 584) | function updateTrayMenu() { function showCustomQuitDialog (line 668) | async function showCustomQuitDialog(type, jobCount) { function runPythonScript (line 945) | function runPythonScript(script, args = [], silent = false, extraEnv = {... function getBackendStatusInternal (line 1005) | async function getBackendStatusInternal(silent = true) { function handleGetStatus (line 1010) | async function handleGetStatus() { function handleGetNotifications (line 1018) | async function handleGetNotifications() { constant CHAT_SESSIONS_V2_FILENAME (line 1511) | const CHAT_SESSIONS_V2_FILENAME = 'chat_sessions_v2.json'; constant CHAT_SESSIONS_LEGACY_FILENAME (line 1512) | const CHAT_SESSIONS_LEGACY_FILENAME = 'chat_sessions.json'; function chatSessionsV2Path (line 1514) | function chatSessionsV2Path() { function chatSessionsLegacyPath (line 1518) | function chatSessionsLegacyPath() { function resetRecordingRuntimeState (line 1849) | function resetRecordingRuntimeState() { function startRecordingRuntimeState (line 1858) | function startRecordingRuntimeState() { function markRecordingPaused (line 1867) | function markRecordingPaused() { function markRecordingResumed (line 1875) | function markRecordingResumed() { function getRecordingElapsedSeconds (line 1886) | function getRecordingElapsedSeconds() { function processNextInQueue (line 1903) | async function processNextInQueue() { function addToProcessingQueue (line 2021) | function addToProcessingQueue(audioFile, sessionName, notesFile) { function setupAutoUpdater (line 2656) | function setupAutoUpdater() { function sendDebugLog (line 2723) | function sendDebugLog(message) { function ensureOllamaRunning (line 3247) | async function ensureOllamaRunning() { function getCloudKeyPath (line 3594) | function getCloudKeyPath() { function saveCloudApiKey (line 3598) | function saveCloudApiKey(key) { function loadCloudApiKey (line 3613) | function loadCloudApiKey() { function hasCloudApiKey (line 3625) | function hasCloudApiKey() { function getOllamaEnv (line 3897) | function getOllamaEnv() { function findOllamaExecutable (line 3912) | async function findOllamaExecutable() { function checkForUpdates (line 3932) | async function checkForUpdates() { function compareVersions (line 3995) | function compareVersions(current, latest) { function getDownloadUrl (line 4010) | function getDownloadUrl(assets) { function getTokenFilePath (line 4151) | function getTokenFilePath() { function saveGoogleTokens (line 4155) | function saveGoogleTokens(tokens) { function loadGoogleTokens (line 4169) | function loadGoogleTokens() { function deleteGoogleTokens (line 4182) | function deleteGoogleTokens() { function getOutlookTokenFilePath (line 4196) | function getOutlookTokenFilePath() { function saveOutlookTokens (line 4200) | function saveOutlookTokens(tokens) { function loadOutlookTokens (line 4214) | function loadOutlookTokens() { function deleteOutlookTokens (line 4227) | function deleteOutlookTokens() { function startGoogleAuth (line 4241) | function startGoogleAuth() { function exchangeCodeForTokens (line 4342) | function exchangeCodeForTokens(code, codeVerifier, port) { function getValidAccessToken (line 4391) | async function getValidAccessToken() { function refreshAccessToken (line 4429) | function refreshAccessToken(refreshToken) { function fetchCalendarEvents (line 4473) | function fetchCalendarEvents(accessToken, maxResults = 7) { function startOutlookAuth (line 4520) | function startOutlookAuth() { function exchangeOutlookCodeForTokens (line 4616) | function exchangeOutlookCodeForTokens(code, codeVerifier, port) { function getValidOutlookAccessToken (line 4664) | async function getValidOutlookAccessToken() { function refreshOutlookAccessToken (line 4701) | function refreshOutlookAccessToken(refreshToken) { function fetchOutlookCalendarEvents (line 4746) | function fetchOutlookCalendarEvents(accessToken, maxResults = 7) { function normalizeOutlookEvent (line 4793) | function normalizeOutlookEvent(event) { function normalizeCalendarEvent (line 4898) | function normalizeCalendarEvent(event) { FILE: app/preload.js constant VERSION (line 12) | const VERSION = 1; FILE: app/renderer/src/App.tsx function App (line 27) | function App() { function RouteView (line 131) | function RouteView({ route }: { route: string }) { function safeDecode (line 155) | function safeDecode(s: string): string { FILE: app/renderer/src/components/AppShell.tsx type AppShellProps (line 6) | interface AppShellProps { function AppShell (line 30) | function AppShell({ FILE: app/renderer/src/components/AskBar.tsx function TranscriptBar (line 27) | function TranscriptBar() { function AskBar (line 85) | function AskBar() { type ChatHeaderProps (line 380) | interface ChatHeaderProps { function ChatHeader (line 393) | function ChatHeader({ type SessionDropdownProps (line 463) | interface SessionDropdownProps { function SessionDropdown (line 470) | function SessionDropdown({ sessions, activeId, onPick, onDelete }: Sessi... type MessageListProps (line 520) | interface MessageListProps { function MessageList (line 526) | function MessageList({ messages, liveText, streaming }: MessageListProps) { function MessageBubble (line 553) | function MessageBubble({ message }: { message: ChatMessage }) { constant SUGGESTION_CHIPS (line 579) | const SUGGESTION_CHIPS: { label: string; prompt: string }[] = [ function deriveSessionName (line 585) | function deriveSessionName(prompt: string): string { FILE: app/renderer/src/components/AudioWave.tsx type AudioWaveProps (line 3) | interface AudioWaveProps { function AudioWave (line 25) | function AudioWave({ FILE: app/renderer/src/components/BottomDockSlot.tsx type BottomDockSlotProps (line 4) | interface BottomDockSlotProps { function BottomDockSlot (line 16) | function BottomDockSlot({ children, bottomOffset = 0 }: BottomDockSlotPr... FILE: app/renderer/src/components/ChatHistoryRow.tsx type ChatHistoryRowSession (line 12) | interface ChatHistoryRowSession { type ChatHistoryRowProps (line 18) | interface ChatHistoryRowProps { function ChatHistoryRow (line 41) | function ChatHistoryRow({ FILE: app/renderer/src/components/FolderScopePicker.tsx type FolderScopePickerProps (line 11) | interface FolderScopePickerProps { function FolderScopePicker (line 23) | function FolderScopePicker({ value, onChange }: FolderScopePickerProps) { FILE: app/renderer/src/components/IconPicker.tsx constant ICON_LIST (line 10) | const ICON_LIST = [ constant ICONS (line 139) | const ICONS = Array.from(new Map(ICON_LIST.map((i) => [i.name, i])).valu... function toPascalCase (line 146) | function toPascalCase(name: string): string { function LucideIcon (line 154) | function LucideIcon({ constant PANEL_W (line 176) | const PANEL_W = 276; constant PANEL_MAX_H (line 177) | const PANEL_MAX_H = 320; constant SEARCH_H (line 178) | const SEARCH_H = 52; constant GAP (line 179) | const GAP = 6; type IconPickerProps (line 181) | interface IconPickerProps { function IconPicker (line 187) | function IconPicker({ anchorRect, onSelect, onClose }: IconPickerProps) { function IconButton (line 353) | function IconButton({ name, onSelect }: { name: string; onSelect: () => ... FILE: app/renderer/src/components/LiveDock.tsx function LiveDock (line 10) | function LiveDock() { function RecordingPill (line 68) | function RecordingPill({ function formatElapsed (line 105) | function formatElapsed(seconds: number): string { FILE: app/renderer/src/components/MainToolbar.tsx type MainToolbarProps (line 20) | interface MainToolbarProps { function MainToolbar (line 28) | function MainToolbar({ function RecordingOptionsPopover (line 170) | function RecordingOptionsPopover() { function formatElapsed (line 229) | function formatElapsed(seconds: number): string { FILE: app/renderer/src/components/MeetingsShell.tsx type MeetingsShellProps (line 37) | interface MeetingsShellProps { function MeetingsShell (line 55) | function MeetingsShell({ type ContextMenuProps (line 323) | interface ContextMenuProps { function ContextMenu (line 332) | function ContextMenu({ function RenamePopover (line 386) | function RenamePopover({ type BuildArgs (line 453) | interface BuildArgs { function buildSidebar (line 460) | function buildSidebar({ meetings, folders, search, activeSummaryFile }: ... function meetingToSidebar (line 490) | function meetingToSidebar(meeting: Meeting, activeSummaryFile: string | ... function formatDateLabel (line 499) | function formatDateLabel(info: Meeting['session_info']): string | undefi... FILE: app/renderer/src/components/QuitDialog.tsx type DialogState (line 6) | interface DialogState { function QuitDialog (line 11) | function QuitDialog() { function CancelButton (line 114) | function CancelButton({ onClick }: { onClick: () => void }) { function ConfirmButton (line 141) | function ConfirmButton({ onClick, label }: { onClick: () => void; label:... FILE: app/renderer/src/components/Sidebar.tsx type SidebarMeeting (line 16) | interface SidebarMeeting { type SidebarFolder (line 24) | interface SidebarFolder { type SidebarContextAction (line 34) | interface SidebarContextAction { constant COLLAPSED_KEY (line 43) | const COLLAPSED_KEY = 'steno-sidebar-collapsed'; constant WIDTH_KEY (line 44) | const WIDTH_KEY = 'steno-sidebar-width'; constant DEFAULT_WIDTH (line 45) | const DEFAULT_WIDTH = 270; constant MIN_WIDTH (line 46) | const MIN_WIDTH = 220; constant MAX_WIDTH (line 47) | const MAX_WIDTH = 480; type Listener (line 53) | type Listener = () => void; function useSidebarCollapsed (line 107) | function useSidebarCollapsed() { function useSidebarWidth (line 119) | function useSidebarWidth() { type SidebarProps (line 129) | interface SidebarProps { function Sidebar (line 144) | function Sidebar({ FILE: app/renderer/src/components/TranscriptPanel.tsx type Segment (line 9) | interface Segment { function TranscriptPanelContent (line 15) | function TranscriptPanelContent({ function TranscriptBody (line 33) | function TranscriptBody({ meeting }: { meeting: Meeting }) { function TranscriptRow (line 99) | function TranscriptRow({ segment, highlight }: { segment: Segment; highl... function renderHighlighted (line 127) | function renderHighlighted(text: string, highlight: string): React.React... function parseTranscript (line 153) | function parseTranscript(meeting: Meeting): Segment[] { FILE: app/renderer/src/components/home/PreviousRow.tsx type PreviousRowProps (line 6) | interface PreviousRowProps { function PreviousRow (line 11) | function PreviousRow({ meeting, folderName }: PreviousRowProps) { function LiveBadge (line 115) | function LiveBadge() { function ProcessingBadge (line 134) | function ProcessingBadge() { function formatTime (line 150) | function formatTime(iso?: string): string | undefined { function formatDuration (line 158) | function formatDuration(seconds?: number): string | undefined { function previewText (line 168) | function previewText(meeting: Meeting): string | undefined { FILE: app/renderer/src/components/home/UpcomingCard.tsx type UpcomingCardProps (line 8) | interface UpcomingCardProps { function UpcomingCard (line 12) | function UpcomingCard({ event }: UpcomingCardProps) { function relativeLabel (line 148) | function relativeLabel(startIso: string): { prefix: string | null; value... function formatStartEnd (line 161) | function formatStartEnd(startIso: string, endIso: string) { FILE: app/renderer/src/components/ui/app-icon.tsx type AppIconProps (line 3) | interface AppIconProps { function AppIcon (line 8) | function AppIcon({ size = 80, className }: AppIconProps) { FILE: app/renderer/src/components/ui/button.tsx type ButtonProps (line 35) | interface ButtonProps FILE: app/renderer/src/components/ui/card.tsx type CardProps (line 19) | interface CardProps FILE: app/renderer/src/components/ui/chip.tsx type ChipProps (line 26) | interface ChipProps FILE: app/renderer/src/components/ui/confirm-dialog.tsx type ConfirmDialogProps (line 13) | interface ConfirmDialogProps { function ConfirmDialog (line 25) | function ConfirmDialog({ FILE: app/renderer/src/components/ui/dialog.tsx function DialogHeader (line 50) | function DialogHeader({ className, ...props }: React.HTMLAttributes['size']>; type Variant (line 26) | type Variant = NonNullable['variant']>; type InputProps (line 28) | interface InputProps type TextareaProps (line 74) | interface TextareaProps FILE: app/renderer/src/components/ui/kbd.tsx function KbdKey (line 4) | function KbdKey({ className, children }: { className?: string; children:... FILE: app/renderer/src/components/ui/row.tsx type RowProps (line 28) | interface RowProps FILE: app/renderer/src/components/ui/tooltip.tsx function TooltipProvider (line 5) | function TooltipProvider({ delayDuration = 120, ...props }: React.Compon... FILE: app/renderer/src/components/ui/typography.tsx type HProps (line 4) | type HProps = React.HTMLAttributes; constant DISPLAY_VAR (line 8) | const DISPLAY_VAR = "'opsz' 144, 'SOFT' 30"; constant H2_VAR (line 9) | const H2_VAR = "'opsz' 96"; function Display (line 11) | function Display({ className, style, ...props }: HProps) { function H1 (line 24) | function H1({ className, style, ...props }: HProps) { function H2 (line 37) | function H2({ className, style, ...props }: HProps) { function H3 (line 50) | function H3({ className, ...props }: HProps) { function Lead (line 59) | function Lead({ function Muted (line 71) | function Muted({ FILE: app/renderer/src/hooks/liveDraftStore.ts type DraftEntry (line 13) | interface DraftEntry { type LiveDraftStore (line 19) | interface LiveDraftStore { function getLiveDraft (line 61) | function getLiveDraft(sessionName: string): DraftEntry | undefined { FILE: app/renderer/src/hooks/useAi.ts function useAiProvider (line 12) | function useAiProvider() { function useSetAiProvider (line 19) | function useSetAiProvider() { function useSetRemoteOllamaUrl (line 42) | function useSetRemoteOllamaUrl() { function useTestRemoteOllama (line 50) | function useTestRemoteOllama() { function useSetCloudApiUrl (line 56) | function useSetCloudApiUrl() { function useSetCloudApiKey (line 64) | function useSetCloudApiKey() { function useSetCloudProvider (line 72) | function useSetCloudProvider() { function useSetCloudModel (line 80) | function useSetCloudModel() { function useTestCloudApi (line 88) | function useTestCloudApi() { FILE: app/renderer/src/hooks/useAiPrompts.ts function useAiPrompts (line 5) | function useAiPrompts() { FILE: app/renderer/src/hooks/useAudioLevel.ts type UseAudioLevelOptions (line 3) | interface UseAudioLevelOptions { function useAudioLevel (line 23) | function useAudioLevel({ FILE: app/renderer/src/hooks/useCalendarEvents.ts type CalendarState (line 6) | type CalendarState = function useCalendarEvents (line 17) | function useCalendarEvents() { function useGoogleCalendarAuth (line 43) | function useGoogleCalendarAuth() { function useOutlookCalendarAuth (line 64) | function useOutlookCalendarAuth() { FILE: app/renderer/src/hooks/useChatSessions.ts type ChatSession (line 5) | type ChatSession = ChatSessionsBlob['sessions'][number]; type ChatMessage (line 6) | type ChatMessage = ChatSession['messages'][number]; function newSessionId (line 8) | function newSessionId() { function emptyBlob (line 12) | function emptyBlob(): ChatSessionsBlob { constant CHAT_KEY (line 16) | const CHAT_KEY = ['chat-sessions'] as const; type LegacyMessage (line 20) | type LegacyMessage = { role: 'user' | 'ai'; content: string }; type LegacySession (line 21) | type LegacySession = { id: string; title: string; messages: LegacyMessag... type LegacyBlob (line 22) | type LegacyBlob = [meetingName: string, sessions: LegacySession[]][]; function migrateLegacyBlob (line 24) | function migrateLegacyBlob(legacy: LegacyBlob): ChatSessionsBlob { function useAllChatSessions (line 50) | function useAllChatSessions() { function useChatSessions (line 66) | function useChatSessions(summaryFile: string | null, meetingName?: strin... FILE: app/renderer/src/hooks/useFolders.ts function useFolders (line 11) | function useFolders() { function useCreateFolder (line 18) | function useCreateFolder() { function useRenameFolder (line 27) | function useRenameFolder() { function useUpdateFolderIcon (line 36) | function useUpdateFolderIcon() { function useDeleteFolder (line 66) | function useDeleteFolder() { function useReorderFolders (line 74) | function useReorderFolders() { function patchMeetingFolders (line 82) | function patchMeetingFolders( function restoreMeetingsSnapshot (line 97) | function restoreMeetingsSnapshot( function useAddMeetingToFolder (line 104) | function useAddMeetingToFolder() { function useRemoveMeetingFromFolder (line 124) | function useRemoveMeetingFromFolder() { FILE: app/renderer/src/hooks/useLiveMeeting.ts function useLiveMeeting (line 6) | function useLiveMeeting() { FILE: app/renderer/src/hooks/useMeetings.ts constant LIVE_SUMMARY_PREFIX (line 13) | const LIVE_SUMMARY_PREFIX = '__live__/'; function useMeetings (line 15) | function useMeetings() { function buildLiveMeeting (line 75) | function buildLiveMeeting( function useMeeting (line 102) | function useMeeting(summaryFile: string | null | undefined) { function useTranscript (line 114) | function useTranscript(summaryFile: string | null | undefined) { function useUpdateMeeting (line 119) | function useUpdateMeeting() { function useDeleteMeeting (line 128) | function useDeleteMeeting() { function useReprocessMeeting (line 136) | function useReprocessMeeting() { function useSaveMeetingNotes (line 145) | function useSaveMeetingNotes() { FILE: app/renderer/src/hooks/useModels.ts function parseSizeGb (line 13) | function parseSizeGb(size?: string): number | undefined { function useModels (line 25) | function useModels() { function useCurrentModel (line 46) | function useCurrentModel() { function useOllamaStatus (line 53) | function useOllamaStatus() { function useSetCurrentModel (line 60) | function useSetCurrentModel() { function usePullModel (line 77) | function usePullModel() { FILE: app/renderer/src/hooks/useRecording.ts type RecordingStatus (line 9) | type RecordingStatus = 'idle' | 'recording' | 'paused' | 'processing'; function useRecording (line 13) | function useRecording() { function useRecordingEvents (line 126) | function useRecordingEvents() { function useRecordingProcessingEffects (line 161) | function useRecordingProcessingEffects() { FILE: app/renderer/src/hooks/useSettings.ts function useNotificationsSetting (line 17) | function useNotificationsSetting() { function useSetNotifications (line 24) | function useSetNotifications() { function useTelemetrySetting (line 32) | function useTelemetrySetting() { function useSetTelemetry (line 39) | function useSetTelemetry() { function useDockIconSetting (line 47) | function useDockIconSetting() { function useSetDockIcon (line 54) | function useSetDockIcon() { function useSystemAudioSetting (line 62) | function useSystemAudioSetting() { function useSetSystemAudio (line 69) | function useSetSystemAudio() { function useLanguageSetting (line 77) | function useLanguageSetting() { function useSetLanguage (line 84) | function useSetLanguage() { function useStoragePath (line 92) | function useStoragePath() { function useSetStoragePath (line 99) | function useSetStoragePath() { function usePickStorageFolder (line 107) | function usePickStorageFolder() { function useAppVersion (line 113) | function useAppVersion() { function useClearSystemState (line 121) | function useClearSystemState() { constant USER_NAME_CACHE_KEY (line 130) | const USER_NAME_CACHE_KEY = 'steno-user-name'; function readCachedUserName (line 132) | function readCachedUserName(): string { function writeCachedUserName (line 140) | function writeCachedUserName(name: string) { function useUserName (line 148) | function useUserName() { function useSetUserName (line 168) | function useSetUserName() { FILE: app/renderer/src/hooks/useSetup.ts function useSetupCheck (line 11) | function useSetupCheck() { function useSetupStep (line 18) | function useSetupStep(name: 'systemCheck' | 'ffmpeg' | 'python' | 'ollam... function useCheckMicPermission (line 28) | function useCheckMicPermission() { function useRequestMicPermission (line 34) | function useRequestMicPermission() { function useDebugLog (line 40) | function useDebugLog() { FILE: app/renderer/src/hooks/useStreamingQuery.ts type StreamStatus (line 4) | type StreamStatus = 'streaming' | 'done' | 'error'; type StreamState (line 6) | interface StreamState { function newId (line 12) | function newId() { function useStreamingQuery (line 16) | function useStreamingQuery() { type StreamingQueryApi (line 155) | type StreamingQueryApi = ReturnType; function StreamingProvider (line 163) | function StreamingProvider({ children }: { children: React.ReactNode }) { function useGlobalStreaming (line 168) | function useGlobalStreaming(): StreamingQueryApi { FILE: app/renderer/src/hooks/useTheme.ts type Theme (line 3) | type Theme = 'light' | 'dark' | 'system'; constant STORAGE_KEY (line 5) | const STORAGE_KEY = 'steno-theme'; function systemPrefersDark (line 7) | function systemPrefersDark(): boolean { function readStoredTheme (line 14) | function readStoredTheme(): Theme { function applyResolved (line 22) | function applyResolved(resolved: 'light' | 'dark') { function useTheme (line 30) | function useTheme() { FILE: app/renderer/src/lib/askBarContext.tsx type AskBarContextValue (line 3) | interface AskBarContextValue { function AskBarProvider (line 13) | function AskBarProvider({ children }: { children: React.ReactNode }) { function useAskBar (line 46) | function useAskBar(): AskBarContextValue { function useActiveMeeting (line 52) | function useActiveMeeting( FILE: app/renderer/src/lib/chat.ts constant GLOBAL_SCOPE (line 7) | const GLOBAL_SCOPE = '__global__'; function deriveSessionName (line 9) | function deriveSessionName(question: string): string { function bucketKey (line 19) | function bucketKey(ts: number, now: number = Date.now()): string { function toBucketLabel (line 50) | function toBucketLabel(key: string): string { function relativeTime (line 64) | function relativeTime(ts: number): string { FILE: app/renderer/src/lib/chatPresets.tsx type ChatPreset (line 6) | interface ChatPreset { constant PRESETS (line 12) | const PRESETS: ChatPreset[] = [ function PresetGlyph (line 39) | function PresetGlyph() { FILE: app/renderer/src/lib/debugLogs.ts constant MAX_LINES (line 12) | const MAX_LINES = 1000; type Listener (line 14) | type Listener = () => void; function notify (line 20) | function notify() { function appendDebugLog (line 24) | function appendDebugLog(line: string) { function clearDebugLogs (line 29) | function clearDebugLogs() { function getDebugLogs (line 35) | function getDebugLogs(): string[] { function subscribeDebugLogs (line 39) | function subscribeDebugLogs(l: Listener): () => void { function primeDebugLogs (line 51) | function primeDebugLogs( FILE: app/renderer/src/lib/ipc.ts type Result (line 11) | type Result = ({ success: true } & T) | { success: false; error: stri... type SessionInfo (line 14) | interface SessionInfo { type Meeting (line 25) | interface Meeting { type Folder (line 43) | interface Folder { type ListedModel (line 51) | interface ListedModel { type CalendarEvent (line 63) | interface CalendarEvent { type Announcement (line 74) | interface Announcement { type UpdateMeetingPatch (line 85) | interface UpdateMeetingPatch { type ChatSessionsBlob (line 93) | interface ChatSessionsBlob { type MicPermissionStatus (line 104) | type MicPermissionStatus = type AiProvider (line 111) | type AiProvider = 'local' | 'remote' | 'cloud'; type CloudProvider (line 112) | type CloudProvider = 'openai' | 'anthropic' | 'custom'; type AppVersionResponse (line 115) | type AppVersionResponse = Result<{ version: string; name: string }>; type StatusResponse (line 116) | type StatusResponse = Result<{ status: string; details?: unknown }>; type SetupCheckResponse (line 117) | type SetupCheckResponse = Result<{ type MicPermissionResponse (line 122) | type MicPermissionResponse = Result<{ status: MicPermissionStatus }>; type MicPermissionGrantResponse (line 123) | type MicPermissionGrantResponse = Result<{ granted: boolean }>; type StartRecordingResponse (line 125) | type StartRecordingResponse = Result<{ message: string; sessionName?: st... type StopRecordingResponse (line 126) | type StopRecordingResponse = Result<{ message: string; sessionName?: str... type PauseRecordingResponse (line 127) | type PauseRecordingResponse = Result<{ message: string }>; type ResumeRecordingResponse (line 128) | type ResumeRecordingResponse = Result<{ message: string }>; type QueueStatus (line 130) | interface QueueStatus { type PickAudioFileResponse (line 141) | type PickAudioFileResponse = Result<{ filePath: string }>; type RecordingsDirResponse (line 142) | type RecordingsDirResponse = Result<{ path: string }>; type ListMeetingsResponse (line 144) | type ListMeetingsResponse = Result<{ meetings: Meeting[] }>; type UpdateMeetingResponse (line 145) | type UpdateMeetingResponse = Result<{ message: string; updatedData: Meet... type DeleteMeetingResponse (line 146) | type DeleteMeetingResponse = Result<{ message: string }>; type SaveMeetingNotesResponse (line 147) | type SaveMeetingNotesResponse = Result<{ path: string }>; type QueryResponse (line 149) | type QueryResponse = Result<{ answer: string }>; type LoadChatSessionsResponse (line 150) | type LoadChatSessionsResponse = Result<{ data: ChatSessionsBlob | null }>; type ListFoldersResponse (line 152) | type ListFoldersResponse = Result<{ folders: Folder[] }>; type CreateFolderResponse (line 153) | type CreateFolderResponse = Result<{ folder: Folder }>; type CheckOllamaResponse (line 155) | type CheckOllamaResponse = Result<{ installed: boolean; path?: string }>; type CheckModelInstalledResponse (line 156) | type CheckModelInstalledResponse = Result<{ installed: boolean }>; type RawSupportedModel (line 157) | interface RawSupportedModel { type ListModelsResponse (line 168) | type ListModelsResponse = Result<{ type GetCurrentModelResponse (line 173) | type GetCurrentModelResponse = Result<{ model: string }>; type GetNotificationsResponse (line 175) | type GetNotificationsResponse = Result<{ notifications_enabled: boolean }>; type GetTelemetryResponse (line 176) | type GetTelemetryResponse = Result<{ type GetDockIconResponse (line 180) | type GetDockIconResponse = Result<{ hide_dock_icon: boolean }>; type GetSystemAudioResponse (line 181) | type GetSystemAudioResponse = Result<{ system_audio_enabled: boolean }>; type GetLanguageResponse (line 182) | type GetLanguageResponse = Result<{ language: string }>; type GetUserNameResponse (line 183) | type GetUserNameResponse = Result<{ user_name: string }>; type StoragePathResponse (line 184) | type StoragePathResponse = Result<{ type PickStorageFolderResponse (line 189) | type PickStorageFolderResponse = Result<{ folderPath: string }>; type GetAiPromptsResponse (line 190) | type GetAiPromptsResponse = Result<{ summarization: string }>; type GetAiProviderResponse (line 192) | type GetAiProviderResponse = Result<{ type AuthStatusResponse (line 201) | type AuthStatusResponse = Result<{ connected: boolean }>; type GetCalendarEventsResponse (line 202) | type GetCalendarEventsResponse = type CheckForUpdatesResponse (line 207) | type CheckForUpdatesResponse = Result<{ type CheckAnnouncementsResponse (line 215) | type CheckAnnouncementsResponse = Result<{ type SummaryChunkEvent (line 221) | interface SummaryChunkEvent { type SummaryTitleEvent (line 225) | interface SummaryTitleEvent { type SummaryCompleteEvent (line 229) | interface SummaryCompleteEvent { type ProcessingCompleteEvent (line 233) | interface ProcessingCompleteEvent { type QueryChunkEvent (line 239) | interface QueryChunkEvent { type QueryDoneEvent (line 243) | interface QueryDoneEvent { type ModelPullProgressEvent (line 248) | interface ModelPullProgressEvent { type ModelPullCompleteEvent (line 252) | interface ModelPullCompleteEvent { type UpdateAvailableEvent (line 257) | interface UpdateAvailableEvent { type UpdateProgressEvent (line 260) | interface UpdateProgressEvent { type UpdateDownloadedEvent (line 263) | interface UpdateDownloadedEvent { type ShortcutStartRecordingEvent (line 266) | interface ShortcutStartRecordingEvent { type RequestFn (line 271) | type RequestFn = (...args: Args) => Promise... type SendFn (line 272) | type SendFn = (...args: Args) => void; type Subscribe (line 273) | type Subscribe

= (cb: (payload: P) => void) => () => void; type StenoaiBridge (line 275) | interface StenoaiBridge { type Window (line 468) | interface Window { function ipc (line 480) | function ipc(): StenoaiBridge { FILE: app/renderer/src/lib/markdown.tsx function renderMarkdown (line 11) | function renderMarkdown(text: string): React.ReactNode { function isTableRow (line 248) | function isTableRow(line: string): boolean { function isTableSeparator (line 258) | function isTableSeparator(line: string): boolean { function splitRow (line 268) | function splitRow(line: string): string[] { function parseAlign (line 295) | function parseAlign(separator: string): ('left' | 'center' | 'right' | n... function renderInline (line 310) | function renderInline(text: string): React.ReactNode { FILE: app/renderer/src/lib/meetingDetailState.ts type StreamPhase (line 9) | type StreamPhase = 'idle' | 'analyzing' | 'generating' | 'done'; type StreamState (line 11) | interface StreamState { FILE: app/renderer/src/lib/meetingsListContext.tsx type MeetingsListActions (line 4) | interface MeetingsListActions { type ProviderProps (line 26) | interface ProviderProps { function MeetingsListProvider (line 31) | function MeetingsListProvider({ onContextAction, children }: ProviderPro... function useMeetingsList (line 62) | function useMeetingsList(): MeetingsListActions | null { FILE: app/renderer/src/lib/result.ts function unwrap (line 3) | function unwrap(result: Result): T { FILE: app/renderer/src/lib/router.ts function useHashRoute (line 3) | function useHashRoute(): string { function routeFromHash (line 15) | function routeFromHash(hash: string): string { function useRoute (line 20) | function useRoute(): string { function navigate (line 24) | function navigate(path: string) { function useNavigate (line 31) | function useNavigate() { function rememberNonSettingsRoute (line 41) | function rememberNonSettingsRoute(route: string) { function getLastNonSettingsRoute (line 45) | function getLastNonSettingsRoute(): string { function toggleSettings (line 54) | function toggleSettings(currentRoute: string) { FILE: app/renderer/src/lib/utils.ts function cn (line 4) | function cn(...inputs: ClassValue[]) { function shortcut (line 17) | function shortcut(mac: string, other: string): string { FILE: app/renderer/src/main.tsx class ErrorBoundary (line 9) | class ErrorBoundary extends React.Component< method constructor (line 13) | constructor(props: { children: React.ReactNode }) { method getDerivedStateFromError (line 17) | static getDerivedStateFromError(error: Error) { method render (line 20) | render() { FILE: app/renderer/src/routes/Chat.tsx function Chat (line 26) | function Chat() { type PendingNewChat (line 353) | interface PendingNewChat { function recordPendingNewChat (line 360) | function recordPendingNewChat(pending: PendingNewChat) { function consumePendingNewChat (line 364) | function consumePendingNewChat(sessionId: string): PendingNewChat | null { function CloudRequiredBanner (line 371) | function CloudRequiredBanner() { function SectionHead (line 399) | function SectionHead({ FILE: app/renderer/src/routes/ChatConversation.tsx type ChatConversationProps (line 35) | interface ChatConversationProps { function ChatConversation (line 39) | function ChatConversation({ sessionId }: ChatConversationProps) { function Bubble (line 462) | function Bubble({ FILE: app/renderer/src/routes/FolderDetail.tsx type FolderDetailProps (line 9) | interface FolderDetailProps { function FolderDetail (line 13) | function FolderDetail({ folderId }: FolderDetailProps) { FILE: app/renderer/src/routes/Home.tsx type HomeProps (line 17) | interface HomeProps { function Home (line 21) | function Home({ mode }: HomeProps) { type SectionHeadProps (line 257) | interface SectionHeadProps { function SectionHead (line 263) | function SectionHead({ title, count, action }: SectionHeadProps) { function summaryLine (line 288) | function summaryLine(_upcomingCount: number): string { function firstFolderName (line 292) | function firstFolderName( type Group (line 301) | interface Group { function groupPrevious (line 306) | function groupPrevious(meetings: Meeting[]): Group[] { function groupLabel (line 327) | function groupLabel(d: Date, now: Date): string { FILE: app/renderer/src/routes/MeetingDetail.tsx constant LAST_OPENED_KEY (line 63) | const LAST_OPENED_KEY = 'steno-last-opened-meeting'; type MeetingDetailProps (line 65) | interface MeetingDetailProps { function MeetingDetail (line 69) | function MeetingDetail({ summaryFile }: MeetingDetailProps) { function DetailContent (line 106) | function DetailContent({ meeting }: { meeting: Meeting }) { function SectionTitle (line 550) | function SectionTitle({ children }: { children: React.ReactNode }) { type ChipV2Props (line 565) | interface ChipV2Props { function ChipV2 (line 571) | function ChipV2({ icon, children, onClick }: ChipV2Props) { type MarkdownBlock (line 609) | interface MarkdownBlock { function parseMarkdownBlocks (line 614) | function parseMarkdownBlocks(text: string): MarkdownBlock[] { constant CHAR_TRANSITION (line 643) | const CHAR_TRANSITION = 'top 0.12s ease-out'; constant ROW_TRANSITION (line 644) | const ROW_TRANSITION = 'top 0.35s cubic-bezier(0.45, 0, 0.55, 1)'; function StreamingView (line 646) | function StreamingView({ text, phase }: { text: string; phase: StreamPha... function CalendarSection (line 803) | function CalendarSection({ meeting }: { meeting: Meeting }) { constant FOLDER_NONE (line 863) | const FOLDER_NONE = '__none__'; constant FOLDER_NEW (line 864) | const FOLDER_NEW = '__new__'; function FolderPicker (line 866) | function FolderPicker({ summaryFile, assignedFolderIds }: { summaryFile:... function formatDetailDate (line 1003) | function formatDetailDate(info: { processed_at?: string; updated_at?: st... function formatDuration (line 1018) | function formatDuration(seconds?: number): string | undefined { function formatEventTime (line 1028) | function formatEventTime(event: CalendarEvent): string { function findRelatedEvents (line 1047) | function findRelatedEvents(events: CalendarEvent[], meeting: Meeting): C... function asStringArray (line 1061) | function asStringArray(value: unknown): string[] { type DiscussionArea (line 1078) | interface DiscussionArea { function asDiscussionAreas (line 1083) | function asDiscussionAreas(value: unknown): DiscussionArea[] { function getErrorMessage (line 1098) | function getErrorMessage(error: unknown): string { FILE: app/renderer/src/routes/Processing.tsx type ProcessingStage (line 16) | type ProcessingStage = 'transcribing' | 'summarizing' | 'finalizing' | '... constant STAGE_LABEL (line 18) | const STAGE_LABEL: Record = { function Processing (line 25) | function Processing() { function StageCard (line 166) | function StageCard({ function ErrorPanel (line 215) | function ErrorPanel({ onRetry }: { onRetry: () => void }) { function ProcessingChip (line 246) | function ProcessingChip() { function Chip (line 262) | function Chip({ function ProcessingDock (line 289) | function ProcessingDock() { function formatDate (line 340) | function formatDate(d: Date): string { function formatDurationEnglish (line 350) | function formatDurationEnglish(seconds: number): string { FILE: app/renderer/src/routes/Recording.tsx function Recording (line 14) | function Recording() { type EditableTitleProps (line 100) | interface EditableTitleProps { function EditableTitle (line 106) | function EditableTitle({ value, onChange, placeholder }: EditableTitlePr... function Chip (line 124) | function Chip({ function formatDate (line 150) | function formatDate(d: Date): string { function formatTime (line 159) | function formatTime(d: Date): string { FILE: app/renderer/src/routes/Sandbox.tsx type SectionProps (line 37) | interface SectionProps { function Section (line 44) | function Section({ id, title, hint, children }: SectionProps) { function Stack (line 60) | function Stack({ function Swatch (line 79) | function Swatch({ name, value }: { name: string; value: string }) { function Sandbox (line 95) | function Sandbox() { FILE: app/renderer/src/routes/Settings.tsx constant COMPACT_TRIGGER (line 87) | const COMPACT_TRIGGER = constant COMPACT_BTN (line 89) | const COMPACT_BTN = 'h-[30px] px-3 text-[13px]'; constant LANGUAGES (line 91) | const LANGUAGES: Array<{ value: string; label: string }> = [ constant TABS (line 106) | const TABS = [ type TabId (line 113) | type TabId = (typeof TABS)[number]['id']; type SettingRowProps (line 119) | interface SettingRowProps { function SettingRow (line 128) | function SettingRow({ function CopyableValue (line 170) | function CopyableValue({ value, mono = false }: { value: string; mono?: ... function SectionHeading (line 210) | function SectionHeading({ children }: { children: React.ReactNode }) { type TabButtonProps (line 225) | interface TabButtonProps { function TabButton (line 231) | function TabButton({ active, onClick, children }: TabButtonProps) { type ModelCardProps (line 255) | interface ModelCardProps { function ModelCard (line 267) | function ModelCard({ function Settings (line 383) | function Settings() { function GeneralTab (line 463) | function GeneralTab() { function AiTab (line 695) | function AiTab() { function RemoteProviderConfig (line 750) | function RemoteProviderConfig() { function CloudProviderConfig (line 807) | function CloudProviderConfig() { function ConnectionStatus (line 1014) | function ConnectionStatus({ type OAuthPromptProps (line 1033) | interface OAuthPromptProps { function OAuthPrompt (line 1045) | function OAuthPrompt({ state, onClose, onRetry }: OAuthPromptProps) { function ModelList (line 1091) | function ModelList() { function AdvancedTab (line 1208) | function AdvancedTab() { function DeveloperTab (line 1351) | function DeveloperTab() { FILE: app/renderer/src/routes/Setup.tsx type StepStatus (line 31) | type StepStatus = 'waiting' | 'running' | 'done' | 'failed'; type Step (line 33) | interface Step { function Badge (line 42) | function Badge({ status }: { status: StepStatus }) { function StepCard (line 66) | function StepCard({ step }: { step: Step }) { function Setup (line 88) | function Setup() { FILE: prompt_tests/test_prompts.py function test_prompt (line 158) | def test_prompt(prompt_name: str, prompt_template: callable, transcript:... function compare_prompts (line 247) | def compare_prompts(transcript_file: str, output_dir: str = None, model:... function cli (line 373) | def cli(): function compare (line 383) | def compare(transcript_file, model, output, prompts): function list_prompts (line 390) | def list_prompts(): function show_prompt (line 403) | def show_prompt(prompt_name, transcript_file): FILE: simple_recorder.py class SimpleRecorder (line 49) | class SimpleRecorder: method __init__ (line 52) | def __init__(self): method get_state (line 73) | def get_state(self) -> dict: method save_state (line 83) | def save_state(self, state: dict): method _resolve_output_language (line 88) | def _resolve_output_language(self, configured_language: str, detected_... method _load_user_notes (line 101) | def _load_user_notes(session_name: str, output_dir) -> Optional[str]: method _parse_streamed_markdown (line 120) | def _parse_streamed_markdown(md_text: str) -> dict: method start_recording (line 170) | def start_recording(self, session_name: str = "Recording") -> str: method stop_recording (line 200) | def stop_recording(self) -> Optional[str]: method transcribe_audio (line 245) | async def transcribe_audio(self, audio_file: str, session_name: str = ... method summarize_transcript (line 324) | async def summarize_transcript( method process_recording (line 398) | async def process_recording(self, audio_file: str, session_name: str =... method process_recording_streaming (line 508) | async def process_recording_streaming(self, audio_file: str, session_n... function cli (line 641) | def cli(): function start (line 648) | def start(session_name): function stop (line 742) | def stop(): function process (line 805) | def process(audio_file, name, notes): function process_streaming (line 839) | def process_streaming(audio_file, name, notes): function get_whisper_model_cmd (line 966) | def get_whisper_model_cmd(): function set_whisper_model_cmd (line 978) | def set_whisper_model_cmd(model_size: str): function get_keep_recordings_cmd (line 993) | def get_keep_recordings_cmd(): function set_keep_recordings_cmd (line 1002) | def set_keep_recordings_cmd(enabled: bool): function status (line 1013) | def status(): function record (line 1042) | def record(duration, session_name): function test (line 1214) | def test(): function _parse_meeting_markdown (line 1269) | def _parse_meeting_markdown(md_path): function list_meetings (line 1383) | def list_meetings(): function reprocess (line 1461) | def reprocess(summary_file, regenerate_title): function regen_title (line 1608) | def regen_title(summary_file): function query (line 1669) | def query(transcript_file, question): function query_streaming (line 1760) | def query_streaming(transcript_file, question): function chat_global_streaming (line 1838) | def chat_global_streaming(question, folder): function list_failed (line 1967) | def list_failed(): function clear_state (line 2028) | def clear_state(): function setup_check (line 2040) | def setup_check(): function list_models (line 2195) | def list_models(): function get_model (line 2295) | def get_model(): function set_model (line 2313) | def set_model(model_name): function get_notifications (line 2336) | def get_notifications(): function set_notifications (line 2352) | def set_notifications(enabled): function get_dock_icon (line 2368) | def get_dock_icon(): function set_dock_icon (line 2380) | def set_dock_icon(enabled): function get_telemetry (line 2396) | def get_telemetry(): function set_telemetry (line 2414) | def set_telemetry(enabled): function get_system_audio (line 2430) | def get_system_audio(): function set_system_audio (line 2442) | def set_system_audio(enabled): function get_language (line 2458) | def get_language(): function set_language (line 2471) | def set_language(language_code): function get_user_name_cmd (line 2497) | def get_user_name_cmd(): function set_user_name_cmd (line 2505) | def set_user_name_cmd(name): function get_storage_path (line 2516) | def get_storage_path(): function set_storage_path (line 2526) | def set_storage_path(storage_path): function list_folders (line 2538) | def list_folders(): function create_folder (line 2548) | def create_folder(name, color): function update_folder_icon (line 2562) | def update_folder_icon(folder_id, icon): function rename_folder (line 2573) | def rename_folder(folder_id, name): function reorder_folders (line 2583) | def reorder_folders(folder_ids): function delete_folder (line 2593) | def delete_folder(folder_id): function add_meeting_to_folder (line 2604) | def add_meeting_to_folder(summary_file, folder_id): function remove_meeting_from_folder (line 2615) | def remove_meeting_from_folder(summary_file, folder_id): function get_ai_provider (line 2624) | def get_ai_provider(): function set_ai_provider (line 2642) | def set_ai_provider(provider): function set_remote_ollama_url (line 2663) | def set_remote_ollama_url(url): function set_cloud_api_url (line 2676) | def set_cloud_api_url(url): function set_cloud_provider (line 2690) | def set_cloud_provider(provider): function set_cloud_model (line 2711) | def set_cloud_model(model): function test_remote_ollama (line 2724) | def test_remote_ollama(url): function test_cloud_api (line 2737) | def test_cloud_api(): function download_whisper_model (line 2770) | def download_whisper_model(): function check_model (line 2792) | def check_model(model_name): function pull_model (line 2829) | def pull_model(model_name): FILE: src/audio_recorder.py function cleanup_sounddevice (line 21) | def cleanup_sounddevice(): class AudioRecorder (line 33) | class AudioRecorder: method __init__ (line 34) | def __init__(self, sample_rate: int = 44100, channels: int = 1): method _load_state (line 53) | def _load_state(self): method _save_state (line 58) | def _save_state(self): method _clear_state (line 62) | def _clear_state(self): method start_recording (line 66) | def start_recording(self) -> None: method stop_recording (line 90) | def stop_recording(self) -> None: method pause_recording (line 105) | def pause_recording(self) -> None: method resume_recording (line 117) | def resume_recording(self) -> None: method is_paused (line 129) | def is_paused(self) -> bool: method _record (line 134) | def _record(self) -> None: method _audio_callback (line 168) | def _audio_callback(self, indata, frames, time, status): method save_recording (line 177) | def save_recording(self, filepath: Path) -> bool: method get_recording_duration (line 217) | def get_recording_duration(self) -> float: method is_recording (line 226) | def is_recording(self) -> bool: method __del__ (line 230) | def __del__(self): FILE: src/config.py class Config (line 16) | class Config: method __init__ (line 134) | def __init__(self, config_path: Optional[Path] = None): method _migrate_cloud_model_map (line 158) | def _migrate_cloud_model_map(self) -> None: method _load (line 179) | def _load(self) -> Dict[str, Any]: method _save (line 194) | def _save(self) -> bool: method _get_default_config (line 205) | def _get_default_config(self) -> Dict[str, Any]: method get_storage_path (line 225) | def get_storage_path(self) -> str: method set_storage_path (line 229) | def set_storage_path(self, storage_path: str) -> bool: method get_model (line 260) | def get_model(self) -> str: method set_model (line 264) | def set_model(self, model_name: str) -> bool: method get_model_info (line 281) | def get_model_info(self, model_name: str) -> Optional[Dict[str, str]]: method list_supported_models (line 293) | def list_supported_models(self) -> Dict[str, Dict[str, str]]: method get_notifications_enabled (line 297) | def get_notifications_enabled(self) -> bool: method set_notifications_enabled (line 301) | def set_notifications_enabled(self, enabled: bool) -> bool: method get_telemetry_enabled (line 314) | def get_telemetry_enabled(self) -> bool: method set_telemetry_enabled (line 318) | def set_telemetry_enabled(self, enabled: bool) -> bool: method get_hide_dock_icon (line 331) | def get_hide_dock_icon(self) -> bool: method set_hide_dock_icon (line 335) | def set_hide_dock_icon(self, enabled: bool) -> bool: method get_keep_recordings (line 349) | def get_keep_recordings(self) -> bool: method set_keep_recordings (line 353) | def set_keep_recordings(self, enabled: bool) -> bool: method get_whisper_model (line 359) | def get_whisper_model(self) -> str: method set_whisper_model (line 367) | def set_whisper_model(self, model_size: str) -> bool: method get_system_audio_enabled (line 375) | def get_system_audio_enabled(self) -> bool: method set_system_audio_enabled (line 379) | def set_system_audio_enabled(self, enabled: bool) -> bool: method get_language (line 392) | def get_language(self) -> str: method set_language (line 396) | def set_language(self, language_code: str) -> bool: method get_language_name (line 413) | def get_language_name(self, language_code: Optional[str] = None) -> str: method get_ai_provider (line 428) | def get_ai_provider(self) -> str: method set_ai_provider (line 433) | def set_ai_provider(self, provider: str) -> bool: method get_remote_ollama_url (line 441) | def get_remote_ollama_url(self) -> str: method set_remote_ollama_url (line 445) | def set_remote_ollama_url(self, url: str) -> bool: method get_cloud_api_url (line 450) | def get_cloud_api_url(self) -> str: method set_cloud_api_url (line 454) | def set_cloud_api_url(self, url: str) -> bool: method get_cloud_api_key (line 459) | def get_cloud_api_key(self) -> str: method get_cloud_provider (line 472) | def get_cloud_provider(self) -> str: method set_cloud_provider (line 477) | def set_cloud_provider(self, provider: str) -> bool: method _get_cloud_models_map (line 485) | def _get_cloud_models_map(self) -> dict: method get_cloud_model (line 494) | def get_cloud_model(self) -> str: method set_cloud_model (line 505) | def set_cloud_model(self, model: str) -> bool: method get_user_name (line 517) | def get_user_name(self) -> str: method set_user_name (line 524) | def set_user_name(self, name: str) -> bool: method get_anonymous_id (line 535) | def get_anonymous_id(self) -> str: method get (line 544) | def get(self, key: str, default: Any = None) -> Any: method set (line 548) | def set(self, key: str, value: Any) -> bool: function get_config (line 558) | def get_config() -> Config: function get_data_dirs (line 566) | def get_data_dirs() -> Dict[str, Path]: FILE: src/folders.py class FoldersManager (line 18) | class FoldersManager: method __init__ (line 21) | def __init__(self, data_dir: Path): method _load (line 25) | def _load(self) -> Dict: method _save (line 34) | def _save(self) -> bool: method list_folders (line 44) | def list_folders(self) -> List[Dict]: method create_folder (line 47) | def create_folder(self, name: str, color: str = "#6366f1") -> Optional... method update_icon (line 61) | def update_icon(self, folder_id: str, icon: str) -> bool: method rename_folder (line 68) | def rename_folder(self, folder_id: str, name: str) -> bool: method delete_folder (line 75) | def delete_folder(self, folder_id: str) -> bool: method reorder_folders (line 81) | def reorder_folders(self, folder_ids: List[str]) -> bool: method _update_md_folders (line 97) | def _update_md_folders(self, summary_path: Path, update_fn) -> bool: method add_meeting_to_folder (line 132) | def add_meeting_to_folder(self, summary_path: Path, folder_id: str) ->... method remove_meeting_from_folder (line 152) | def remove_meeting_from_folder(self, summary_path: Path, folder_id: st... function get_folders_manager (line 173) | def get_folders_manager() -> FoldersManager: FILE: src/models.py class ActionItem (line 7) | class ActionItem(BaseModel): class Decision (line 13) | class Decision(BaseModel): class DiscussionArea (line 19) | class DiscussionArea(BaseModel): class MeetingTranscript (line 24) | class MeetingTranscript(BaseModel): method to_json_file (line 35) | def to_json_file(self, filepath: str) -> None: method from_json_file (line 42) | def from_json_file(cls, filepath: str) -> 'MeetingTranscript': FILE: src/ollama_manager.py function get_bundled_ollama_dir (line 22) | def get_bundled_ollama_dir() -> Optional[Path]: function get_ollama_binary (line 51) | def get_ollama_binary() -> Optional[Path]: function get_ollama_env (line 99) | def get_ollama_env() -> dict: function is_ollama_running (line 130) | def is_ollama_running() -> bool: function _get_pid_file (line 146) | def _get_pid_file() -> Path: function _write_pid (line 153) | def _write_pid(pid: int) -> None: function _clear_pid (line 161) | def _clear_pid() -> None: function start_ollama_server (line 169) | def start_ollama_server(wait: bool = True, timeout: int = 30) -> bool: function run_ollama_command (line 222) | def run_ollama_command(args: list, timeout: int = 300) -> Tuple[bool, st... function pull_model (line 253) | def pull_model(model_name: str, progress_callback=None) -> bool: function list_models (line 309) | def list_models() -> list: function has_model (line 334) | def has_model(model_name: str) -> bool: FILE: src/summarizer.py class OllamaSummarizer (line 19) | class OllamaSummarizer: method __init__ (line 20) | def __init__(self, model_name: Optional[str] = None): method _is_ollama_running (line 98) | def _is_ollama_running(self) -> bool: method _find_ollama_path (line 102) | def _find_ollama_path(self) -> Optional[str]: method _start_ollama_service (line 110) | def _start_ollama_service(self) -> bool: method _repair_json (line 115) | def _repair_json(self, json_text: str) -> Optional[str]: method _create_enhanced_fallback (line 158) | def _create_enhanced_fallback(self, malformed_response: str, transcrip... method _ensure_model_available (line 232) | def _ensure_model_available(self) -> bool: method _ensure_ollama_ready (line 278) | def _ensure_ollama_ready(self) -> bool: method _cloud_chat (line 296) | def _cloud_chat(self, prompt: str, timeout_seconds: int = 300) -> str: method _openai_chat (line 311) | def _openai_chat(self, prompt: str, timeout_seconds: int = 300) -> str: method _anthropic_chat (line 333) | def _anthropic_chat(self, prompt: str, timeout_seconds: int = 300) -> ... method _create_permissive_prompt (line 359) | def _create_permissive_prompt(self, transcript: str, language: str = "... method summarize_transcript (line 476) | def summarize_transcript(self, transcript: str, duration_minutes: int,... method _create_markdown_prompt (line 664) | def _create_markdown_prompt(self, transcript: str, language: str = "en... method summarize_transcript_streaming (line 711) | def summarize_transcript_streaming(self, transcript: str, duration_min... method test_connection (line 773) | def test_connection(self) -> bool: method set_model (line 807) | def set_model(self, model_name: str) -> bool: method cleanup (line 833) | def cleanup(self): method __del__ (line 848) | def __del__(self): method generate_title (line 852) | def generate_title(self, summary: str, transcript: str, language: str ... method _build_query_prompt (line 933) | def _build_query_prompt(self, transcript: str, question: str, language... method query_transcript_streaming (line 950) | def query_transcript_streaming(self, transcript: str, question: str, l... method query_transcript (line 1004) | def query_transcript(self, transcript: str, question: str, language: s... FILE: src/transcriber.py class WhisperTranscriber (line 40) | class WhisperTranscriber: method __init__ (line 48) | def __init__(self, model_size: str = "small"): method _ensure_ffmpeg_in_path (line 67) | def _ensure_ffmpeg_in_path(self) -> None: method _load_model (line 135) | def _load_model(self) -> None: method _load_whisper_cpp (line 148) | def _load_whisper_cpp(self) -> None: method _load_openai_whisper (line 161) | def _load_openai_whisper(self) -> None: method transcribe_audio (line 168) | def transcribe_audio(self, audio_filepath: Path, language: str = "en")... method _convert_to_16khz (line 227) | def _convert_to_16khz(self, audio_filepath: Path) -> tuple: method _transcribe_whisper_cpp (line 278) | def _transcribe_whisper_cpp(self, audio_filepath: Path, language: str ... method _transcribe_openai_whisper (line 343) | def _transcribe_openai_whisper(self, audio_filepath: Path, language: s... method _split_stereo_to_channels (line 367) | def _split_stereo_to_channels(self, audio_filepath: Path) -> Tuple[Opt... method _check_rms_energy (line 440) | def _check_rms_energy(self, audio_path: Path, threshold: float = 0.005... method transcribe_diarised (line 474) | def transcribe_diarised(self, audio_filepath: Path, language: str = "e... method transcribe_with_timestamps (line 564) | def transcribe_with_timestamps(self, audio_filepath: Path) -> Optional... method change_model (line 604) | def change_model(self, model_size: str) -> bool: method get_backend_info (line 626) | def get_backend_info(self) -> dict: FILE: tests/test_config.py class ConfigStoragePathTests (line 9) | class ConfigStoragePathTests(unittest.TestCase): method test_set_storage_path_handles_permission_errors (line 10) | def test_set_storage_path_handles_permission_errors(self): method test_set_storage_path_accepts_none_as_reset (line 21) | def test_set_storage_path_accepts_none_as_reset(self): class ConfigLanguageTests (line 29) | class ConfigLanguageTests(unittest.TestCase): method test_set_language_accepts_supported_dutch_code (line 30) | def test_set_language_accepts_supported_dutch_code(self): method test_set_language_accepts_auto_detection_mode (line 38) | def test_set_language_accepts_auto_detection_mode(self): class ConfigWhisperModelTests (line 47) | class ConfigWhisperModelTests(unittest.TestCase): method test_default_whisper_model_is_small (line 48) | def test_default_whisper_model_is_small(self): method test_set_whisper_model_persists_supported_size (line 53) | def test_set_whisper_model_persists_supported_size(self): method test_set_whisper_model_rejects_unknown_size (line 63) | def test_set_whisper_model_rejects_unknown_size(self): method test_get_whisper_model_falls_back_when_stored_value_invalid (line 69) | def test_get_whisper_model_falls_back_when_stored_value_invalid(self): class ConfigKeepRecordingsTests (line 77) | class ConfigKeepRecordingsTests(unittest.TestCase): method test_default_keep_recordings_is_false (line 78) | def test_default_keep_recordings_is_false(self): method test_keep_recordings_round_trip (line 83) | def test_keep_recordings_round_trip(self): FILE: tests/test_transcriber.py class WhisperTranscriberAutoLanguageTests (line 8) | class WhisperTranscriberAutoLanguageTests(unittest.TestCase): method _build_transcriber (line 9) | def _build_transcriber(self, model: Mock) -> WhisperTranscriber: method test_auto_mode_uses_detected_language (line 17) | def test_auto_mode_uses_detected_language(self): method test_auto_mode_falls_back_when_detection_fails (line 31) | def test_auto_mode_falls_back_when_detection_fails(self): method test_explicit_language_skips_auto_detection (line 45) | def test_explicit_language_skips_auto_detection(self): FILE: website/src/App.jsx function App (line 12) | function App() { FILE: website/src/analytics.js function trackDownload (line 3) | function trackDownload(location, arch) { function trackGitHub (line 7) | function trackGitHub(location) { FILE: website/src/components/Brand.jsx function StenoMark (line 1) | function StenoMark({ size = 22, className = "" }) { function Wordmark (line 34) | function Wordmark({ size = 19 }) { FILE: website/src/components/ThemeToggle.jsx function ThemeToggle (line 4) | function ThemeToggle() { FILE: website/src/sections/CTAFooter.jsx constant DOWNLOAD_ARM (line 5) | const DOWNLOAD_ARM = "https://github.com/ruzin/stenoai/releases/latest/d... constant DOWNLOAD_X64 (line 6) | const DOWNLOAD_X64 = "https://github.com/ruzin/stenoai/releases/latest/d... function CTAFooter (line 8) | function CTAFooter() { FILE: website/src/sections/FAQ.jsx function FAQ (line 14) | function FAQ() { FILE: website/src/sections/Features.jsx function Features (line 13) | function Features() { FILE: website/src/sections/Footer.jsx constant GITHUB_URL (line 4) | const GITHUB_URL = "https://github.com/ruzin/stenoai"; function Footer (line 6) | function Footer() { FILE: website/src/sections/Hero.jsx constant DOWNLOAD_ARM (line 6) | const DOWNLOAD_ARM = "https://github.com/ruzin/stenoai/releases/latest/d... function fmt (line 8) | function fmt(s) { function Hero (line 15) | function Hero() { FILE: website/src/sections/HowItWorks.jsx function HowItWorks (line 25) | function HowItWorks() { FILE: website/src/sections/Industries.jsx function Industries (line 10) | function Industries() { FILE: website/src/sections/Models.jsx function Models (line 13) | function Models() { FILE: website/src/sections/Nav.jsx constant GITHUB_URL (line 7) | const GITHUB_URL = "https://github.com/ruzin/stenoai"; function Nav (line 9) | function Nav() { FILE: website/src/sections/TrustStrip.jsx function TrustStrip (line 10) | function TrustStrip() {