{"slug":"dear-bubbe-nextjs","total":21,"limit":100,"offset":0,"since":null,"commits":[{"hash":"e629a02","date":"2026-07-21 12:33:26 -0700","author":"Steve Abrams","subject":"fix(auth): route NextAuth errors to /auth/signin + Secure session cookie on prod","body":"pages.signIn/error both pointed at '/', which silently swallowed every\nauth error code — the new ?error= banner could never fire. Session cookie\nwas explicitly secure:false on an HTTPS-only prod; now NODE_ENV-keyed.\n(Contrarian-gate findings, both verified in source.)\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>"},{"hash":"2aee9f0","date":"2026-07-21 12:23:54 -0700","author":"Steve Abrams","subject":"fix(auth): surface NextAuth ?error= on signin page + pin turbopack root","body":"Failed Google OAuth previously bounced back to /auth/signin silently (the\npage ignored the error query param), making sign-in failures undiagnosable.\nNow maps AccessDenied/OAuthCallback/OAuthSignin/Configuration to friendly\nbanners. turbopack.root + outputFileTracingRoot pinned so stray $HOME\nlockfiles stop breaking/warning builds.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>"},{"hash":"7b8743d","date":"2026-07-17 08:45:58 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-17T08:45:54 (1 files) — package-lock.json","body":""},{"hash":"35d9212","date":"2026-07-17 08:34:39 -0700","author":"Steve Abrams","subject":"chore: v0.2.0 (session close) — lint clean, refactor done + contrarian-gated in-session","body":""},{"hash":"557b99d","date":"2026-07-17 07:44:32 -0700","author":"Steve Abrams","subject":"fix(bubbe/mobile): create SpeechRecognition once + latest-ref for onresult","body":"The mic useEffect recreated a SpeechRecognition instance on every isSpeaking/\nisLoading change (pre-existing since d6aa0de). Now created once; the once-bound\nonresult calls handleSendRef.current so it always uses the freshest\nhandleSendMessage (session/mode closure) instead of the initial render's.\nDesktop left as-is (its recreate is load-bearing for auto-restart).\n\nText chat + build verified green (WebKit); voice needs a real-device test."},{"hash":"3899565","date":"2026-07-17 07:41:08 -0700","author":"Steve Abrams","subject":"refactor(bubbe): delete dead ExpandableChat + VoiceManager","body":"Both unreachable from the live page→BubbeResponsive→Mobile/Desktop chain\n(ExpandableChat had 0 importers; VoiceManager only imported by ExpandableChat).\nRemoves the Finding-C overlap/retry-storm landmine the contrarian flagged.\nBuild clean, homepage 200."},{"hash":"f3aff35","date":"2026-07-16 18:01:26 -0700","author":"Steve Abrams","subject":"refactor(bubbe): typed SpeechRecognition shim + drop dead window flag","body":"- new types/speech.d.ts: WebSpeechRecognition interface + Window augmentation\n  (distinct name to avoid clobbering lib.dom); kills the (window as any) casts\n  and the untyped recognitionRef in both components\n- removed MobileBubbe's vestigial __bubbeAutoStarted window flag (gated nothing;\n  mobile uses the welcome-screen buttons, not auto-start)\n- kept DesktopBubbe's __bubbeDesktopAutoStarted (legit StrictMode remount guard)\n- DTD verdict B (incremental-safe); deferred the speech-setup extraction — mic\n  lifecycle can't be verified headless, needs a real-device test\n\nVerified: build clean, homepage 200, chat + console clean (WebKit)."},{"hash":"6ac4af5","date":"2026-07-16 17:49:14 -0700","author":"Steve Abrams","subject":"debug+refactor(bubbe): fix social-post ENOENT, extract shared chat/voice lib, drop dead components","body":"DEBUG:\n- api/social-post: logs/ dir didn't exist -> writeFile ENOENT on every trigger.\n  Now mkdir -p the dir + use process.cwd() instead of a hardcoded mac path.\n\nREFACTOR:\n- new lib/bubbeChat.ts: guestGateBlocks (free-chat gate), fetchBubbeReply (AI call),\n  makeVoicePlayer (stop-before-play + synchronous overlap lock) — the exact logic\n  that was triplicated and got edited twice in one session, now in ONE place.\n- MobileBubbe + DesktopBubbe consume the lib; playBubbeVoice/handleSendMessage\n  collapse to thin wrappers (mobile: mode==='voice'; desktop: voiceEnabled + auto-listen).\n- removed dead components SimpleConversation.tsx + SimplifiedChat.tsx (0 imports).\n\nVerified: build clean, homepage 200, chat + free-chat gate work (WebKit), console 0 errors,\nvoice-overlap logic preserved verbatim."},{"hash":"0dbdfa0","date":"2026-07-16 17:43:58 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-16T17:43:55 (3 files) — app/api/social-post/route.ts components/SimpleConversation.tsx components/SimplifiedChat.tsx","body":""},{"hash":"84b91bc","date":"2026-07-16 17:37:50 -0700","author":"Steve Abrams","subject":"fix(csp): allow Cloudflare Insights beacon (+ GA4 regional) — clears console CSP refusal","body":"- script-src: + https://static.cloudflareinsights.com\n- connect-src: + https://cloudflareinsights.com https://*.google-analytics.com https://www.google.com\n- verified on WebKit: console now 0 errors, chat unaffected; /api/auth/providers stays 200 (that '404' was a false reading, no fix needed)"},{"hash":"f7be260","date":"2026-07-16 17:26:25 -0700","author":"Steve Abrams","subject":"fix(voice): Bubbe never speaks over herself + slightly faster speech","body":"- synchronous isSpeakingRef lock (React state updated too late to block a rapid 2nd call)\n- create the ONE Audio element once, not on every state change (was orphaning mid-play clips → overlap)\n- hard pause+reset before each new clip (stop-before-play)\n- ElevenLabs voice_settings speed 1.08 (a little faster, still natural)\n- verified PASS by click-through agent: max concurrent audio == 1 across Chrome/Safari/Browserbase"},{"hash":"bffe4c6","date":"2026-07-16 17:13:53 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-16T17:13:50 (2 files) — components/DesktopBubbe.tsx components/MobileBubbe.tsx","body":""},{"hash":"c7ca51c","date":"2026-07-16 16:53:14 -0700","author":"Steve Abrams","subject":"feat(bubbe.ai): free chat — 3 messages before Google sign-in (mobile-first)","body":"- page.tsx: render chat for guests instead of hard-redirecting to /auth/signin\n- MobileBubbe/DesktopBubbe: gate send after 3 free messages (localStorage), then trigger Google sign-in\n- restores the intended '3 free messages' onboarding so mobile users can chat immediately"},{"hash":"242ce89","date":"2026-07-16 11:58:27 -0700","author":"Steve Abrams","subject":"deploy(bubbe.ai): OpenAI-primary chat, drop standalone for next start, strip em-dash key override from ecosystem","body":"- chat: OpenAI gpt-3.5-turbo primary (fast, funded), Ollama last-resort (Anthropic out of credits)\n- next.config: disable output:standalone so `next start` serves + loads .env.local\n- ecosystem: remove hardcoded ANTHROPIC_API_KEY placeholder (em-dash crashed every request); keys come from .env.local; USE_ANTHROPIC=0"},{"hash":"9778c1c","date":"2026-05-31 17:20:01 -0700","author":"SteveStudio2","subject":"security: redact/env-ify remaining ELEVENLABS_API_KEY copies in docs + voice-monitor.sh","body":""},{"hash":"b794837","date":"2026-05-31 17:18:42 -0700","author":"SteveStudio2","subject":"security: env-ify ELEVENLABS_API_KEY (was hardcoded in pm2 ecosystem env)","body":""},{"hash":"c7a098c","date":"2026-05-31 00:10:41 -0700","author":"SteveStudio2","subject":"security: remove malware launcher (/var/tmp/.font/n0de) from dev/start scripts + built artifact; gitignore .next","body":""},{"hash":"d88e7a9","date":"2026-05-30 23:52:02 -0700","author":"SteveStudio2","subject":"gitignore: add backup/source-leak patterns (*.bak, *.orig, etc.)","body":"Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"b54eb99","date":"2026-05-29 08:14:18 -0700","author":"Steve","subject":"Update Claude model IDs to claude-opus-4-8 (Opus 4.8 upgrade)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e5ab1dd","date":"2026-05-07 12:29:23 -0700","author":"Steve","subject":"tighten .gitignore: add missing standing-rule patterns (tmp/ *.log dist/)","body":""},{"hash":"d6aa0de","date":"2026-05-06 10:20:46 -0700","author":"Steve","subject":"initial snapshot — gitify all builds (CLAUDE.md rule 2026-05-06)","body":""}]}