Spaces:
Sleeping
Sleeping
Commit History
-
Drop reflective_question from dimension-event cards
Not wanted on this card type after seeing it rendered. Removed end to end rather than just hiding it in the UI — the prompt no longer asks Claude to generate it, so there's no wasted output tokens on text that was never going to be shown. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>99aec30 -
Route dimension-event phrasing through Claude, batched (Option B)
Home feed's maturity cards (Vocabulary Richness, Pace, etc.) were pure Python string templates — the same one-of-five sentence shapes forever, which is why they read as flat next to Session Recap's Claude-written cards, and why the same dimension crossing into "steady" in two scopes at once produced two near-duplicate cards back to back. The trigger decision itself (trigger_detector.py's if/elif logic — which of the 5 rules applies) is untouched and stays fully deterministic; that decision is a numeric threshold comparison and must stay reliable, not a place for LLM judgment. Only the phrasing step changes: every event that fires in one finalize run is now batched into a single Claude call (new pipeline/event_phraser.py) with the decided facts, the same dimension's state in its sibling scope, a few neighboring signals from the session, and the dimension's last-fired note for anti-repetition. Events for the same dimension firing in multiple scopes in one run are grouped into ONE card i…70d37d2
-
Reflected Back cards: match left-border color to the signal's own dot
Border pulled from framing type (Observation/Strength/Growth area — 3 colors) while the bullet dot pulled from the signal's own fixed color (14 colors, same ones used for that signal on the Home feed and spectrum chart) — same card, two unrelated color systems, looked broken. Border now follows the dot's color; the framing badge pill keeps its own color since it conveys separate information. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>3a2b5d9 -
Clicking the header logo/wordmark returns to Home
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>743fe31 -
Remove raw filename from session header, un-cap spectrum intro width
The session detail header showed the internal upload filename (meet_segment_2.webm) — not meaningful to a user, dropped it along with the now-unused filename/detected_speaker destructures. Session Spectrum's intro paragraph had maxWidth: 62ch, appropriate for reading text but making it sit cramped on the left above cards that span the full width. Removed the cap. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>3efe926 -
Distinct colors per conversation type on History
Every session card and filter chip used the same blue regardless of context, so the list read as visually flat. Each context now gets its own fixed color (grouped by display label, since several raw context keys collapse to the same label — e.g. social/casual both render as "Casual & Low-Stakes" and must share a color). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>186c898 -
Session detail: auto-dismiss saved banner, one-card-at-a-time observations
"Session saved" banner sat there permanently instead of reading as a confirmation toast — now fades out ~4s after mount. Behavioral observation cards fit ~3 per screen in the horizontal scroller, so it read as a normal grid rather than a scrollable stack. Cards are now sized to the container (88%) so one is dominant and the next peeks in at the edge as a scroll affordance. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>974780e
-
Richer empty states for new users on Home and You
Bare "your mirror is waiting" text gave no sense of what's coming and no next action. Home now shows a real example card (faded "Example" badge) so a new user sees the feed instead of just reading about it; You lists what the standing portrait will contain. Both add an "Open Google Meet" CTA since recording can only start from an actual call. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>0338292 -
Recording segment cap, 4-step onboarding, Google OAuth fix, upgrade card, Home feed polish
- offscreen.js/background.js: recording now hard-caps at MAX_CHUNKS=2 (40 min total) instead of continuing indefinitely. The final segment routes through background.js's normal handleStop() (WebRTC-timeline flush before stopping) instead of a plain boundary cut, so the last chunk's speaker timeline is complete. The 30s pre-boundary warning now distinguishes "continuing automatically" from "recording will end." - AuthView.jsx: fixed the Google sign-in button being hidden specifically inside the extension (display:none leftover from before the chrome.identity.launchWebAuthFlow path existed) — handleGoogle() already supported both contexts, only the button visibility was wrong. Added diagnostic logging for the OAuth callback failure path. - OnboardingView.jsx: rebuilt to 4 steps (Concept/How/Preview/Trust) — Preview is new, showing an example portrait card (real quote+tags format, not numeric scores) plus a compact "Already reflected back" hint and an honest "what …401c4a8
-
Scope onboarding-done state per account, not per browser
bm_onboarding_v1 was a single flat localStorage key with no user scoping — once any account finished onboarding on a browser, every other account signing in on that same browser (e.g. a friend testing on your machine, or you testing a second account) silently skipped it too. Now keyed as bm_onboarding_v1_<user.id> and re-checked whenever the signed-in user actually changes, not just once at mount.9d84a97
-
Bring onboarding, How It Works, and privacy policy up to date
These hadn't been touched since the CLAUDE.md engine rebuild and were describing a product that no longer exists: voice enrollment, the disabled Upload path, a 5-trait Confidence/Assertiveness/Composure radar, Groq Whisper transcription, pyannote diarization. All fully removed in favor of what's actually true today: Deepgram Nova-3, Claude for phrasing, no diarization (the mic identifies you by construction), and real self-relative signals with no numeric grades. Onboarding goes from 2 steps to 3 — dropping the dead "Upload" path freed up room for a dedicated trust/privacy step ("What happens to your recording"), rather than the one small gray footnote it was buried in before. That same "only your patterns are kept, whoever else is on the call is never profiled" point now appears consistently in onboarding, How It Works, the privacy policy, and the recording consent modal — a real, distinctive design decision that wasn't stated anywhere in the product until now.88c192b
-
Fix HistoryView Retry button sending page=[object Object]
onClick={loadSessions} passed React's click SyntheticEvent as the first argument (pageNum), which then got template-interpolated straight into the request URL — confirmed in production logs as repeated 422s on GET /api/sessions?page=[object%20Object].c93687d -
Home recap: drop resonance vote, add colored signal label
The vote already lives on the session detail page (voting twice on the same observation was redundant); Home's card now just shows the observation and its reflective question. Also replaces the hardcoded signal->color lookup (which only covered old signal-key names and silently fell back to gray for the free-form names the LLM actually generates, e.g. "topic_transition") with a deterministic hash-based color picker shared between Home and the session detail page, so every signal gets a real color and the same signal reads the same color on both surfaces.b6afdb8 -
Rebuild History/session-detail into 3 CLAUDE.md-compliant tabs
Replaces the old Dimensions tab (numeric 1-5 trait scores) and the per-participant speaker-timeline chart (rule #8: persisted behavioral signals for every other room participant, indefinitely) with: - Session Spectrum: 7 composites (Speech Style, Vocal Arousal, Rapport, Power Balance, Turn-taking Courtesy, Fluency, Responsive Engagement), each a self-relative "more/less than your usual" read computed by z-scoring components against their own history at read-time, never a stored raw score. New evidence_gate.py layer, verified with 18 synthetic checks. - Overview: metrics-first ordering, Notable Pattern removed (redundant + violated rule #3), Behavioral Observations horizontal-scroll with the resonance-vote layout fixed (vote now sits against the observation, not the adjacent reflective question) and tips attached via existing coaching_suggestions[].dimension_key matching. - HistoryView: dropped the numeric score dots and the speaker-timeline chart, added one self-re…31abd7f
-
Complete the password reset flow; fix feedback email sender
AuthView gains an "update-password" mode (new password + confirm, calls supabase.auth.updateUser) and App.jsx now catches Supabase's PASSWORD_RECOVERY auth event to route there before the normal app/onboarding. The reset email's redirectTo now points at the extension's own fullpage URL (built dynamically via chrome.runtime.getURL, not hardcoded), since there's no hosted copy of the app to redirect to otherwise. manifest.json declares index.html as a web_accessible_resource — without it, Chrome silently blocks external navigation into the extension with ERR_BLOCKED_BY_CLIENT, which is what an actual end-to-end test surfaced. Also switches the feedback-notification email's sender to Resend's shared sandbox address (onboarding@resend.dev) so it works with any API key immediately, rather than requiring mirrorai.live's domain to be verified in Resend first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>454186b -
Revert to the bar-graph logo
The Dome/Clarity mark didn't land well in practice — reverting App.jsx, AuthView, OnboardingView, HowItWorksView, ProfileView's empty state, favicon.svg, generate-icons.html, and the extension icon PNGs to their pre-dome-mark state, and removing the now-unused Logo.jsx. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>7dd0d81 -
Replace the bar-graph logo with the Dome/Clarity mark
Introduces a single shared Logo.jsx component (DomeMark + LogoLockup) and retires 5 independently hand-duplicated copies of the old equalizer-bar SVG across App.jsx, AuthView, OnboardingView, HowItWorksView, and ProfileView's empty state. The new mark matches docs/Mirror_Canonical_Vision.md's "Clarity" mark: a faint dashed dome above the mirror line, a solid dome below rendered with a radial gradient (bright center, deepening toward the edges). Also rewrites favicon.svg and generate-icons.html to match, and regenerates the extension's icon16/48/128.png against a dark background rather than the old near-black canvas default. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>f9393f8
-
Rebuild the You page: fix stale 9-signal bug, add paragraph/tags/indicators/coaching
Rewrites Shape/Reflected Back/How You Shift By Context's shared signal-key maps against the current 15-dimension set (they were still keyed on the old 9-signal names, silently clamping ~10 dimensions to the chart's max), adds categorical axis support, and adds a per-signal color palette. Adds three new You-page sections built on the existing evidence-gated portrait system: a self-referential narrative paragraph + behavior-phrase tags, a plain-fact indicators strip (session count, time recorded, avg talk-share/pace, contexts covered), and coaching synthesis ("Where You Might Grow") that distills recurring coaching_suggestions grouped by a new dimension_key field. Recadences the existing signals/context-shift synthesis call from every-session to every-3- sessions, adds Shape's established-vs-recent overlay, curates Signal History down to 7 signals, and renames "What We've Noticed" to "Reflected Back". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>22395e0
-
Home feed v2: 15-dimension evidence engine + trigger-detection + interleaved feed
Replaces the static 9-signal/5-card-type Home feed with a real evidence-gated system: 15 tracked dimensions (was 9, plus 3 fold-in sub-signals), a new categorical evidence path for signals whose mean sits near zero (pacing/energy arc), and a trigger-detection engine that diffs each session's evidence against persisted state to fire one of 5 event types (first-time-steady, drift, recurring, context-shift, single-session anomaly) with a shared 2-session cooldown. Home now interleaves an unconditional per-session recap card with these frozen, dated dimension events instead of recomputing static cards from live evidence on every read. Also reformulates 5 signal computations (curiosity as a rate, room-wide interruptions, a 4-input reweighted drive score, a building-on-others denominator fix, and fixed-window vocabulary richness to remove a session-length confound), and adds two new Supabase tables (signal_evidence_state, dimension_events) to support the trigger engine. Co-Authored-By: Cla…9ceaaad
-
Fix still-forming cards mislabeling stable-but-noisy signals; add audio diagnostics
still_forming (Home + You page) was including signals that already had enough samples but were still too variable (high CV) to call steady — these showed as "6 of 5 sessions" and would never resolve since more sessions alone don't fix variance. Now omitted entirely once the sample floor is met but steadiness still isn't reached (say nothing rather than mislabel), confirmed against the exact real-account scenario that surfaced this. Also clamps both progress-bar widths defensively. Adds non-invasive diagnostic logging (track mute/unmute, AudioContext state, RTCPeerConnection connection state) to the WebRTC injector and offscreen recorder, investigating intermittent audio dropout reports during live testing — pure logging, no behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>c1392fe
-
Phase B3 second slice: replace Mirror Feed with evidence-gated Home feed
Retires the LLM free-form mirror_feed/recurring_coaching system (no dismissal awareness, session-count-gated patterns) in favor of five card types built from already-computed evidence and portrait data: strength, observation, how-it-may-land, progress, and still-forming. Cards are self-relative, carry their evidence, and are dismissable via a new dismissed_cards table — dismissing a growth_area/observation framing of a signal shares one key so it holds even if the portrait LLM later reclassifies it. Home is now the app's default landing tab. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>7d68132
-
Phase B3, You page: evidence-based standing portrait replaces trait scoring
Retires the numeric dimension-scoring "personality" system from the You page (pentagon chart, 0-100 dimension scores, personality-trait badges — the clearest CLAUDE.md rule #2 violation in the app) and replaces it with a standing portrait built entirely on the 9 relational signals' evidence-gating system from Phase B2. Scoped to the You page only, per earlier decision: dimension_scorer.py keeps running unchanged, still feeding HistoryView and ResultsView's dimension displays — untouched this slice. - New backend/pipeline/portrait_synthesizer.py: replaces PersonalitySynthesizer's role. Only phrases signals that are already evidence-steady, classifies each qualitatively (strength / growth_area / observation, never a number), and phrases cross-context comparisons for signals steady in 2+ of the user's own contexts. Reuses the existing Groq call pattern (Claude migration stays deferred per earlier decision). - main.py: new _compute_profile_evidence() computes evidence for all 9…ed3866e
-
Phase B1: quarantine pyannote/voiceprint off the live path, remove Upload UI
Per CLAUDE.md rule #1 (no diarization/voiceprint guessing on the live path), now that the mic-capture keystone means the user is identified by construction. Changes: - backend/main.py: removed the pyannote diarize() + voiceprint-matching fallback branch from _run_prepare_job entirely. When no WebRTC speaker timeline is available, the job now fails cleanly with a clear error instead of silently guessing the speaker. Also removed _update_voiceprint() (was unconditionally running pyannote embeddings on every session, including WebRTC-mode ones — a live-path violation this audit surfaced). diarizer.merge_transcript_with_speakers() stays; it's a transcript/timeline merge utility, not diarization itself, and the WebRTC path depends on it. pipeline/diarizer.py and pipeline/voiceprint.py are left in place (quarantined, not deleted) for a possible future upload-a-file feature. - Frontend: removed the Upload nav tab + UploadView, and the "Train your voice" account-menu entr…0507574 -
Self-heal a 401 mid-chunk by refreshing the auth token on demand
prepare and finalize can now be several minutes apart (2 transcriptions, diarization, signal extraction, scoring, an LLM call) — long enough for the Supabase token cached at recording-start to go stale before finalize runs, which surfaced as "Finalize failed (HTTP 401): Invalid or expired token" during mic-capture verification. background.js now retries once on a 401 by asking any open extension page to force-refresh its session via getSession() (which refreshes on demand if expired) and reports the fresh token back over runtime messaging. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>ae18cb8 -
Route mic permission through a dedicated extension tab; parallelize mic+tab transcription
getUserMedia's permission prompt cannot render inside a side panel or popup (confirmed Chromium limitation) — it silently rejected with no UI. Adds request-mic.html/js, a minimal extension tab that can show the real prompt; the side panel now opens it only when permission isn't already granted, and waits for the result via a message + tab-close listener. Also runs the new mic transcription concurrently with the existing tab transcribe/diarize pipeline (background ThreadPoolExecutor) instead of sequentially before it, to cut the added backend latency roughly in half. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>5c375d9 -
Capture the user's own mic as a second stream in Meet recording
Previously only tab audio (other participants) was recorded and transcribed; the user's own mic was used for VAD timing only, so their speech content never appeared anywhere. Adds a second, synchronized MediaRecorder on getUserMedia({audio:true}) in the offscreen document, uploads it alongside the existing tab stream, and transcribes it independently on the backend into a new mic_transcript field — never merged into the existing tab-based transcript/diarization/scoring pipeline. Bootstraps mic permission from the visible side panel since the offscreen document can't show its own prompt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>9cf6c37
-
Add job timeout watchdog, session pagination, feedback modal, and store assets
- Backend: 15-min per-job timeout using threading.Timer + _cancelled set; fires at every existing cancellation checkpoint in both prepare and finalize jobs - Backend: GET /api/sessions now paginated (page/page_size params, returns total + has_more) - Frontend: HistoryView loads 10 sessions at a time with a "Load more" button that appends - Frontend: FeedbackModal component wired into Account menu → Send feedback - Landing: CNAME for mirrorai.live custom domain - Store assets: listing copy, screenshots template, promo tile for CWS submission Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0580b30
-
Replace password toggle emoji with SVG eye icons
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>dd61d52 -
Hide Google OAuth button in extension context
Continue with Google is hidden in the Chrome extension side panel since it requires a separate Chrome Extension OAuth client setup. Email/password auth works for all users in extension context. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>fb84c92 -
Revert implicit flowType — use PKCE so Supabase exchanges code server-side
With flowType implicit, Supabase set our extension URL as Google's redirect_uri directly, meaning we received a raw Google auth code that can't be exchanged client-side. With PKCE (default), Supabase handles the exchange via its own callback and redirects to our extension URL with a Supabase-issued code that exchangeCodeForSession can handle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>28baf74 -
Fix Google OAuth callback: check query params and hash, show real error
Supabase can return tokens in query params or hash depending on version. Also surface the actual OAuth error string instead of generic message. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>15fae7a -
Fix Google OAuth in Chrome extension: implicit flow + PKCE fallback
- Set flowType:'implicit' in Supabase client so tokens come in the URL hash, which is what launchWebAuthFlow captures (PKCE sends a code that requires a server-side exchange, not usable in an extension callback) - Handle both implicit (hash access_token) and PKCE (query code) in callback so it works regardless of Supabase project settings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>254e7f6 -
Fix tab capture: always get fresh stream ID on-demand + propagate offscreen errors
Pre-fetched stream IDs expire in ~10 seconds, so using them when the user finally clicks Start Recording caused silent "Error starting tab capture". - handleStart: try on-demand getMediaStreamId first (always fresh); pre-fetched is now a last-resort fallback only - handleStart: check offscreen sendMessage response and return the error instead of blindly setting recordingActive = true even when capture failed - Bump consent key to v3 so the one-time modal re-appears after this fix Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0be84d5 -
Fix backend round(dict) crash + tab capture permission + consent/results UX
- Fix TypeError in backend: logger was calling round() on dimension group dicts (dimensions values are nested dicts, not scalars) - Fix tab capture "Extension has not been invoked": moved getMediaStreamId to background SW action.onClicked (where activeTab grant lives); removed it from panel page which can never hold that grant - Switch openPanelOnActionClick to false + manual sidePanel.open() so activeTab grant reaches the SW correctly - Bump consent key to mirror_consent_v2 so existing users see the modal again - Remove 5-second auto-dismiss on analysis results; add persistent "View in History" button instead - Wire onViewHistory prop through App → MeetStatusBanner → history nav Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>886eaea -
Update recording consent message to be friendlier
Reframes from "you must get consent" to "this is for your personal growth, here's what we do with it, and please give others a heads up." Compliant with Chrome Web Store requirements while being less heavy-handed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1e8e010 -
Add open-as-full-page feature
- Small expand icon button in the header (side panel only) opens the extension as a full browser tab at index.html?fullpage=1 - Full page mode: wider layout (900px, 40px side padding vs 600px/24px), no MeetStatusBanner (recording belongs in the side panel) - Expand button hidden when already in full page or not in extension context - isExtension and isFullPage are module-level constants so they don't recompute on every render Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1417226 -
Redesign onboarding to 2 steps + add recording consent prompt
Onboarding: - Cut from 3 steps to 2: concept screen (what Mirror is) + how-to screen (two paths: Google Meet live recording vs file upload) - Step 2 now accurately describes the current product — removed the old "upload only" framing, added Meet recording path with clear description - CTA changed to "Open the mirror →" on final step - Removed StepPreview (mock profile) — reduces time to first real use Recording consent: - First-time "Start Recording" click now shows a modal: "You are responsible for ensuring all participants consent to being recorded" - User must confirm before recording starts; choice stored in localStorage (mirror_consent_v1) so prompt never appears again Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>aff2ced -
Remove enrollment gate, add 15-session monthly cap
- App.jsx: enrollment no longer blocks access — removed the voiceprint status check and the blocking EnrollView screen. Voice training stays available in Account menu as an optional setting. - main.py: /api/prepare/start checks monthly session count before processing; returns 429 when >= 15 sessions used this month. New /api/usage endpoint returns used/limit/remaining/resets_on. - UploadView: shows a subtle session usage bar (turns orange at ≤3 remaining, red at 0) and disables the upload button when limit is hit. Refreshes usage count after each successful analysis. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>edee3c4
-
LLM-generated portrait tags (max 4, behavior-specific)
PersonalitySynthesizer now outputs 3-4 keyword tags grounded in fingerprint observations (e.g. "Reframes Questions", "Topic Driver") rather than fixed score-bucket labels. ProfileView uses personality.tags from the API instead of the old deriveKeywords() mapping. Bump _SYNTHESIS_VERSION to 7 to invalidate cached portraits. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2e7ca87 -
Restore dot-grid background
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a65851a -
Portrait layout, clean background, richer Recurring Themes
- Portrait: text justified full-width, keyword tags in a row below (not side-by-side) - index.css: remove dot-grid overlay so panel background is clean dark (not grey) - main.py: normalize coaching area synonyms (Active Listening → Listening, etc.) and capture the latest suggestion text per area - ProfileView: Recurring Themes shows "{N} of {total} sessions" count + tip text so each card explains what to work on, not just a label with a flagged count Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>dbd59f3 -
Mirror feed: gradient fade on 3rd item with Show more overlay
Replace the separate button with a gradient that fades the bottom of the 3rd card from transparent to the page background (#0f1117), with a "Show more" pill overlaid on it. Clicking anywhere on the gradient expands the feed. "Show less" appears as a plain text link below when expanded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a88c856 -
Richer portrait + collapsible mirror feed
PersonalitySynthesizer: - Paragraph rules now direct the LLM across 7 behavioral vocabulary dimensions: thinking style, argument framing, conversation navigation, handling challenge, clarity/precision, listening quality, warmth/relational style - Session log now passes fingerprint[:350] (was [:200]) as the PRIMARY source rather than raw dimension scores — the qualitative text matters more - Explicit rule: do NOT make dominance/talk ratio the portrait centrepiece if fingerprints reveal more interesting things - Bump _SYNTHESIS_VERSION 5 → 6 to force portrait regeneration ProfileView: - MirrorFeed is now collapsible — shows 3 items by default - "Show N more" button expands to full list - "Show less" collapses back to 3 - Extracted MirrorFeedItem component for cleaner rendering Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6744cd1 -
Remove reflect tab — saves one full LLM call per session
Each session was making a separate 800-token reflection-questions call on top of the main 3000-token insight call. The content overlapped with resonance_prompts already embedded in observations and the coaching tab. Removing the tab, the backend call, and the three generator methods. Finalize job is now 3 steps instead of 4. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b665409 -
Major feature update: Google Meet recording, cumulative mirror feed, UX overhaul
Backend: - Fix talk ratio inflation for multi-speaker Google Meet calls (use all_other_segs) - Add user_perspective field to InsightGenerator — user now feels personally seen - Mirror feed is now cumulative: items persist, evolve, and grow across sessions (v4) - Expose per-speaker WPM timeline in /api/sessions for history chart - Bump _MF_VERSION to 4 to force feed regeneration with new cumulative logic Frontend: - Google Meet WebRTC recording: content-meet.js + meet-webrtc-injector.js + offscreen audio pipeline - Speaker timeline chart in History tab (who spoke when, WPM per participant) - ProfileView: Portrait section moved above Mirror Feed (it's the centrepiece) - ProfileView: Recurring Themes section added (coaching areas flagged across sessions) - ResultsView: Summary tab removed, summary_sentence block removed - ResultsView: "Your Perspective" section added (user_perspective from InsightGenerator) - ResultsView: Visual 3-segment talk split bar (You / Others / Silence) - Results…5748a9d
-
Fix get_sessions 500 crash + extension panel stability
- backend/main.py: wrap each session in try/except in get_sessions so one malformed JSON field no longer crashes the entire endpoint with 500 - HistoryView: add loadError state and Retry button instead of silently showing "No sessions yet" when the API fails - MeetStatusBanner: sync a fresh Supabase token to the SW right before recording starts, preventing stale-JWT 401s on chunk upload - background.js: skip getMediaStreamId prefetch when already recording - manifest.json: add "tabs" permission for reliable Meet URL detection - vite.config.js: base "./" for correct extension asset paths - background.js: call sidePanel.open() before any await so it fires within Chrome's user-gesture window Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8f4ee21
-
Rename to mirror., scroll reveal animations, waveform logo, deployment config
- Renamed app from Behavioral Mirror to mirror. throughout - Added waveform SVG logo (option 2A) to all pages replacing emoji placeholders - Added scroll reveal animations (Reveal/RevealItem) to all pages - Cleaned requirements.txt: removed unused anthropic, openai-whisper, whisperx, sqlalchemy - Added Dockerfile with CPU-only torch and ffmpeg for Railway deployment - Updated CORS to allow chrome-extension:// origins via regex + FRONTEND_URL env var - Added .env.example template Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d1cde70
-
Profile intelligence, context-aware baselines, and Mirror Feed
Core additions: - Personality synthesis with paragraph + 5 scored dimensions (PersonalitySynthesizer) - Context-specific baselines: population norms per context type → personal context average once 3+ same-context sessions exist. Eliminates false-positive coaching (e.g. high talk ratio in evaluative contexts no longer flagged as domination) - Mirror Feed: per-session highlight feed on profile page, collapsed with peek effect - Reflect tab: pre-computed session Q&A (generate_reflection_questions) - Transcript quotes extracted and passed to profile synthesis for grounded narratives - Onboarding flow (3-step, localStorage gated) - Session delta: flags dimension score changes ≥8pts after each new session - Blind spots: top 3 context gaps the mirror hasn't seen - Profile completeness bar with depth label - Context detector pipeline stage (ContextDetector via Groq) - Voice enrollment UI (EnrollView) with 1–3 round recording - Auth UI (AuthView), Supabase client, API client - SSE-based pr…d4c6e81
-
Parallel transcription, SSE reliability fixes, HistoryView optimisation
- Parallelize Whisper + pyannote in prepare job using ThreadPoolExecutor (~4 min saved) - Add voiceprint.py speaker embedding module (pyannote/embedding, 70/30 blend) - Fix SSE done message dropped on stream close (asyncio.sleep flush before break) - Add onerror fallback: fetch result from DB if SSE drops after job completes - Reset UploadView to idle state after results delivered (no stuck finalizing screen) - Keep HistoryView always mounted; re-fetch only on tab activation (stops GET flooding) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bd77e3e
-
Dimension scoring, expanded signals, and full results UI overhaul
- Add DimensionScorer with 4 behavioral dimensions (emotional state, relational dynamics, communication effectiveness, conversation arc), each with 5 sub-scores - Expand SignalExtractor with vocal energy, speech acceleration, questions, monologue detection, vocabulary richness, silence ratio, and notable signal detection - Add baseline comparison after 3+ sessions - Update InsightGenerator to include dimensions and transcript in LLM prompt, produce conversation summary and dimension narrative - Wire dimensions through main.py pipeline and database - Overhaul ResultsView to display all new signals and dimension scores Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b18547f