Skip to content

Podcast notes AI prefix#686

Merged
kentcdodds merged 4 commits intomainfrom
cursor/podcast-notes-ai-prefix-a84a
Feb 24, 2026
Merged

Podcast notes AI prefix#686
kentcdodds merged 4 commits intomainfrom
cursor/podcast-notes-ai-prefix-a84a

Conversation

@kentcdodds
Copy link
Owner

@kentcdodds kentcdodds commented Feb 24, 2026

Add an AI disclosure prefix to notes for Call Kent podcast recordings generated from typed text.


Open in Web Open in Cursor 


Note

Low Risk
Small, isolated formatting change for prefilled call notes plus unit tests and docs; no auth, persistence, or core request handling changes.

Overview
Typed-question (text-to-speech) call submissions now prefill notes with a standardized format that prepends the AI voice disclosure and labels the content as Typed question: while preserving internal newlines.

This introduces formatCallKentTextToSpeechNotes (with de-dupe/empty handling) and adds unit coverage for trimming, newline preservation, duplicate-prefix stripping, and blank input. Docs also note that cloud/headless Chrome may need mic/camera permissions to avoid /calls/record/new hitting the ErrorBoundary.

Written by Cursor Bugbot for commit 106863a. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Call notes for text-to-speech now prepend an AI-voice disclosure and standardize "Typed question" formatting, de-duplicating disclosures and preserving internal newlines.
  • Tests

    • Added unit tests covering trimming, newline preservation, duplicate-disclosure handling, and empty/whitespace cases.
    • Added a reusable in-memory test cache and a reset helper for semantic-search tests; tests now use the helper to reset state.
  • Documentation

    • Added cloud/headless manual testing guidance for call recording (camera/microphone and localhost access).

@cursor
Copy link

cursor bot commented Feb 24, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replace direct trimming with a new formatter formatCallKentTextToSpeechNotes for Call Kent prefill notes, add unit tests covering multiple input cases, introduce an in-memory test cache helper for semantic-search tests, and document cloud/headless testing for mic/camera access.

Changes

Cohort / File(s) Summary
TTS Notes Formatter
app/utils/call-kent-text-to-speech.ts, app/routes/calls_.record/new.tsx
Add formatCallKentTextToSpeechNotes(questionText) and replace simple trim with this formatter when assembling Call Kent prefill notes; handles trimming and AI disclosure prefix normalization.
Formatter Tests
app/utils/__tests__/call-kent-text-to-speech-notes.test.ts
Add 5 unit tests covering trimming, internal newline preservation, disclosure-prefix deduplication, and empty/whitespace-only input behavior.
Test Cache Helper
tests/semantic-search-test-cache.ts, app/utils/__tests__/semantic-search-cache.server.test.ts, app/utils/__tests__/semantic-search.server.test.ts
Introduce in-memory memory and testCache, a cachifiedSpy mock, and resetSemanticSearchTestCache() helper; tests now call the helper instead of manually clearing state.
Documentation
docs/agents/project-context.md
Add "Cloud / headless manual testing" subsection explaining Chrome camera/mic blocking in cloud VMs and advising to allow localhost mic/camera to avoid ErrorBoundary on /calls/record/new.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 I nudged the notes with careful paws,
Trimmed the fluff and fixed the flaws,
Prefixed the voice so words align,
Tests hopped in to make it fine,
A little thump — tidy TTS applause. 🎙️

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Podcast notes AI prefix' is vague and generic, using non-descriptive phrasing that doesn't clearly convey the actual changes made to the codebase. Consider using a more specific title like 'Add AI disclosure prefix to Call Kent podcast notes' that better describes the primary change and functionality being implemented.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/podcast-notes-ai-prefix-a84a

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kentcdodds kentcdodds marked this pull request as ready for review February 24, 2026 18:23
@cursor cursor bot force-pushed the cursor/podcast-notes-ai-prefix-a84a branch from 5663c46 to c6a5abb Compare February 24, 2026 18:29
@cursor

This comment has been minimized.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
app/utils/__tests__/call-kent-text-to-speech-notes.test.ts (1)

7-28: Tests are correct and will pass — missing coverage for the empty-input branch

All three test cases correctly exercise the implementation. However, the function's early-exit branch — if (!cleaned) return cleaned — is left untested. An empty string and a whitespace-only string are both valid inputs worth asserting on.

✅ Suggested additional test cases
+test('returns empty string for whitespace-only input', () => {
+	expect(formatCallKentTextToSpeechNotes('   ')).toBe('')
+})
+
+test('returns empty string for empty input', () => {
+	expect(formatCallKentTextToSpeechNotes('')).toBe('')
+})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/__tests__/call-kent-text-to-speech-notes.test.ts` around lines 7 -
28, Add tests covering the early-exit branch in formatCallKentTextToSpeechNotes:
call formatCallKentTextToSpeechNotes('') and formatCallKentTextToSpeechNotes('  
') and assert they return an empty string (i.e., the cleaned value), which
exercises the if (!cleaned) return cleaned branch in the function; add these two
assertions to the existing test file alongside the other cases so the
empty/whitespace inputs are explicitly covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/utils/__tests__/call-kent-text-to-speech-notes.test.ts`:
- Around line 7-28: Add tests covering the early-exit branch in
formatCallKentTextToSpeechNotes: call formatCallKentTextToSpeechNotes('') and
formatCallKentTextToSpeechNotes('   ') and assert they return an empty string
(i.e., the cleaned value), which exercises the if (!cleaned) return cleaned
branch in the function; add these two assertions to the existing test file
alongside the other cases so the empty/whitespace inputs are explicitly covered.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6a5abb and 0d633b9.

📒 Files selected for processing (2)
  • app/utils/__tests__/call-kent-text-to-speech-notes.test.ts
  • app/utils/call-kent-text-to-speech.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/utils/call-kent-text-to-speech.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/semantic-search-test-cache.ts`:
- Around line 4-19: Add a reset helper that clears module-global state to avoid
cross-test leakage: implement a function (e.g., resetTestCache) that calls
memory.clear() and cachifiedSpy.mockReset() (or vi.resetAllMocks for the spy),
export it alongside memory, testCache, and cachifiedSpy, and call that helper
from a test lifecycle hook (e.g., beforeEach(() => resetTestCache())) so the Map
`memory`, the cache wrapper `testCache`, and the spy `cachifiedSpy` are reset
between tests.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d633b9 and 7d017c4.

📒 Files selected for processing (2)
  • app/utils/__tests__/call-kent-text-to-speech-notes.test.ts
  • tests/semantic-search-test-cache.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/utils/tests/call-kent-text-to-speech-notes.test.ts

Comment on lines +4 to +19
export const memory = new Map<string, unknown>()

export const testCache = {
name: 'semantic-search-test-cache',
get(key: string) {
return (memory.get(key) as any) ?? null
},
async set(key: string, entry: unknown) {
memory.set(key, entry)
},
async delete(key: string) {
memory.delete(key)
},
}

export const cachifiedSpy = vi.fn(baseCachified as any)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a reset hook to prevent cross-test cache leakage.

memory and cachifiedSpy are module‑global and never cleared, so tests can become order‑dependent. Consider adding a reset helper plus a beforeEach to ensure isolation.

♻️ Suggested fix
-import { vi } from 'vitest'
+import { beforeEach, vi } from 'vitest'
@@
 export const cachifiedSpy = vi.fn(baseCachified as any)
+
+export const resetTestCache = () => {
+	memory.clear()
+	cachifiedSpy.mockClear()
+}
+
+beforeEach(() => {
+	resetTestCache()
+})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/semantic-search-test-cache.ts` around lines 4 - 19, Add a reset helper
that clears module-global state to avoid cross-test leakage: implement a
function (e.g., resetTestCache) that calls memory.clear() and
cachifiedSpy.mockReset() (or vi.resetAllMocks for the spy), export it alongside
memory, testCache, and cachifiedSpy, and call that helper from a test lifecycle
hook (e.g., beforeEach(() => resetTestCache())) so the Map `memory`, the cache
wrapper `testCache`, and the spy `cachifiedSpy` are reset between tests.

@cursor cursor bot force-pushed the cursor/podcast-notes-ai-prefix-a84a branch from 7d017c4 to e7b8987 Compare February 24, 2026 19:19
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is ON. A Cloud Agent has been kicked off to fix the reported issue.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
app/utils/__tests__/call-kent-text-to-speech-notes.test.ts (1)

22-28: Consider adding a case-insensitive prefix de-dup test.

The formatter explicitly does a case-insensitive comparison (cleaned.toLowerCase().startsWith(prefixLower)), but no test exercises that path. A user pasting the prefix in a different case (e.g., all-caps) would still trigger de-duplication.

💡 Suggested additional test
+test('removes duplicate AI disclosure regardless of casing', () => {
+	const question = `${AI_VOICE_DISCLOSURE_PREFIX.toUpperCase()} Hello from a typed call.`
+	const notes = formatCallKentTextToSpeechNotes(question)
+	expect(notes).toBe(
+		`${AI_VOICE_DISCLOSURE_PREFIX}\nTyped question: Hello from a typed call.`,
+	)
+})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/__tests__/call-kent-text-to-speech-notes.test.ts` around lines 22 -
28, Add a new unit test that verifies formatCallKentTextToSpeechNotes removes
the AI_VOICE_DISCLOSURE_PREFIX regardless of casing: create a question string
that uses a different case variant of AI_VOICE_DISCLOSURE_PREFIX (e.g., upper-
or mixed-case) followed by a typed question and assert the output matches the
expected deduplicated form (prefix on its own line and "Typed question: ..."
text); reference AI_VOICE_DISCLOSURE_PREFIX and formatCallKentTextToSpeechNotes
so the test targets the case-insensitive startsWith path in that function.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/utils/__tests__/call-kent-text-to-speech-notes.test.ts`:
- Around line 22-28: Add a new unit test that verifies
formatCallKentTextToSpeechNotes removes the AI_VOICE_DISCLOSURE_PREFIX
regardless of casing: create a question string that uses a different case
variant of AI_VOICE_DISCLOSURE_PREFIX (e.g., upper- or mixed-case) followed by a
typed question and assert the output matches the expected deduplicated form
(prefix on its own line and "Typed question: ..." text); reference
AI_VOICE_DISCLOSURE_PREFIX and formatCallKentTextToSpeechNotes so the test
targets the case-insensitive startsWith path in that function.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d017c4 and 2ab9042.

📒 Files selected for processing (7)
  • app/routes/calls_.record/new.tsx
  • app/utils/__tests__/call-kent-text-to-speech-notes.test.ts
  • app/utils/__tests__/semantic-search-cache.server.test.ts
  • app/utils/__tests__/semantic-search.server.test.ts
  • app/utils/call-kent-text-to-speech.ts
  • docs/agents/project-context.md
  • tests/semantic-search-test-cache.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/utils/call-kent-text-to-speech.ts
  • tests/semantic-search-test-cache.ts

@cursor
Copy link

cursor bot commented Feb 24, 2026

Bugbot Autofix prepared fixes for 1 of the 1 bugs found in the latest run.

  • ✅ Fixed: Duplicated prefix-stripping logic across two files
    • Moved the prefix-stripping helper into the shared utility and reused it in both callers to eliminate duplication.

cursoragent and others added 4 commits February 24, 2026 19:35
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@cursor cursor bot force-pushed the cursor/podcast-notes-ai-prefix-a84a branch from 25ac7fa to 106863a Compare February 24, 2026 19:39
@kentcdodds kentcdodds merged commit e1cc4fd into main Feb 24, 2026
8 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Feb 24, 2026
@kentcdodds kentcdodds deleted the cursor/podcast-notes-ai-prefix-a84a branch February 24, 2026 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants