Skip to content

fix(workflows): encode non-ASCII sender names for ses - #589

Closed
Silthus wants to merge 3 commits into
masterfrom
fix/email-from-name-encoding
Closed

Silthus wants to merge 3 commits into
masterfrom
fix/email-from-name-encoding

Conversation

@Silthus

@Silthus Silthus commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Problem

  • Workflows email steps that send from a name with non-ASCII characters, such as "Café Müller", put raw UTF-8 into the SES From header.
  • SES requires a non-ASCII friendly name as an RFC 2047 encoded word (SES docs), so such a send can fail or show a garbled name.
  • A sender name override also lost its quotes, angle brackets and backslashes, because the service stripped them.
  • Found in review of the email domain wizard (#521), which works around it with a fallback name.

Impact

Pays into Grow Workflows through the email activation rate (measured here). In scope: email, Messaging. Expected move: small, up. Run cost: n/a.

Warning

🟡 Merge risk: medium · one-way door: an email sent with a wrong From name stays sent (merge-risk rubric)

  • Every SES send builds its From and To headers through formatMailbox. A bug there fails or garbles real sends for any team.
  • Limits: ASCII names keep the exact header they get today, and only non-ASCII names and overrides with "<>\ take a changed branch. Unit and SES-command tests cover each branch. A revert restores the old headers.

Changes

  • A non-ASCII sender or recipient name now reaches SES as a UTF-8 base64 encoded word, for example =?UTF-8?B?Q2Fmw6kgTcO8bGxlcg==?= <a@example.com>. Mail clients show "Café Müller".
  • An ASCII name keeps today's RFC 5322 quoted string, byte for byte. Encoding every name would change every send's header, and spam filters score a needlessly encoded From (SpamAssassin FROM_EXCESS_BASE64).
  • A sender name override now keeps quotes, angle brackets and backslashes inside the escaped name. Control characters are still dropped, so a templated name cannot inject a header.
  • The local maildev path now hands nodemailer a { name, address } object. Nodemailer encodes it itself, and it would show a pre-encoded word as literal text.
  • A long name spans several encoded words of at most 45 bytes each. The split falls only between code points, so a character such as 𠮷 never breaks. Nodemailer's encodeWord breaks it, which is why the service does not use it.

How did you test this code?

  • Lane gate on 3ace43f (a rebase of fd42eee onto fresh upstream master): tsc --noEmit clean on fd42eee, eslint and oxlint clean on the changed files, email.service.test.ts green against local Postgres and maildev.
  • CI: not run. Fork CI cannot run because the fork lacks the GitHub App secret. The full gate runs when this PR moves to PostHog/posthog.
  • Not run: a send through real SES. This devbox has no SES sandbox credentials, and the local SES emulator does not enforce the 7-bit rule.

Test rationale:

  • formatMailbox table, one new row: a non-ASCII name becomes an encoded word. It catches the bug itself. The expected base64 comes from Python's base64, not from the code.
  • formatMailbox round trip for a long CJK name with 𠮷 and a long emoji name: each word decodes per RFC 2047 to the exact name and stays within 75 characters. It catches a split inside a character. The CJK row failed with nodemailer's encoder.
  • SES from overrides table: the old "sanitized" row now expects quotes, angle brackets and a backslash kept and escaped. A new row sends a non-ASCII name with quotes. They catch the SES wiring and any return of the stripping.
  • Maildev send test, now parameterized with a non-ASCII recipient name. It catches double encoding on the nodemailer path, which an encoded string in to would cause.

Test seams: formatMailbox, and EmailService.executeSendEmail observed at the SES SendEmailCommand input and at the maildev inbox.

Owed proofs:

  • Live run: partial evidence, below. Base and HEAD From values for six names were each parsed by Python's RFC 5322/2047 header parser. HEAD values are 7-bit ASCII and decode to the exact input name.
  • Prod shape: gap. Measuring the share of stored sender names with non-ASCII characters needs read-only production access, which arrives on 2026-11-02. Standing rule accepts it until then.
  • Post-deploy watch: owed after the merge.
From header at base and HEAD fd42eee, decoded by Python's email parser
input='Café Müller'
  base: sent='"Café Müller" <sender@example.com>'  7-bit ASCII: False
  HEAD: sent='=?UTF-8?B?Q2Fmw6kgTcO8bGxlcg==?= <sender@example.com>'  7-bit ASCII: True  decoded='Café Müller' intact=True
input='Café "Müller"'
  base: sent='"Café \\"Müller\\"" <sender@example.com>'  7-bit ASCII: False
  HEAD: sent='=?UTF-8?B?Q2Fmw6kgIk3DvGxsZXIi?= <sender@example.com>'  7-bit ASCII: True  decoded='Café "Müller"' intact=True
input='Dry\\Run "Co"'
  base and HEAD: sent='"Dry\\\\Run \\"Co\\"" <sender@example.com>'  decoded='Dry\\Run "Co"' intact=True
input='Ünïcødé Sender with a fairly long organization name GmbH & Co. KG'
  HEAD: two encoded words, longest 72 characters, decoded intact=True
input='株式会社山田商事部𠮷田' repeated 4 times
  HEAD: encoded words, longest 72 characters, decoded intact=True
input='Plain Sender'
  base and HEAD: sent='"Plain Sender" <sender@example.com>'

Release status

  • No feature flag controls this change

Docs update

None. No doc under docs/ covers how the email service formats sender names.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)

  • A side fix split from the email domain wizard work at Michael's request.
  • Skills invoked: impact, tdd, /writing-tests, qa-swarm design pass, pr-description, /writing-pr-descriptions, merge-risk.
  • Design pass: GPT-6.1 Sol (high), Design and Anti-Overengineering lenses. One finding, rejected, see Decisions.
  • Review: GPT-6.1 Sol (high). Round 1 found the split inside 𠮷, fixed in 3ace43f. The final read found nothing.
  • No duplicate: a search of open PRs on PostHog/posthog and this fork found no other fix for display-name encoding.
  • Public artifact: every name and address in tests and evidence is invented.
Question Answer Who Where
Keep or strip "<>\ in a sender name override? Keep them escaped inside the quoted name, as the side-fix brief asked; strip only control characters 🤖 Agent pending approval
Encode every name, as the design pass suggested? No. Encode only non-ASCII names, so ASCII headers stay byte for byte and avoid FROM_EXCESS_BASE64 🤖 Agent pending approval
Own encoder or nodemailer's? Own encoder that splits on code points; replaced nodemailer's encodeWord after review showed it breaks 𠮷 🤖 Agent pending approval

Involvement: no grilling rounds, one design pass and two review rounds (GPT-6.1 Sol), live-run evidence captured.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🤖 CI report

⚠️ Complexity (TypeScript) — 314 functions above the limit (max 118)

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

Function Location Complexity Limit
InternalDataTableVisualization frontend/src/queries/nodes/DataVisualization/DataVisualization.tsx:205 118 10
AIObservabilityEvaluation products/ai_observability/frontend/evaluations/AIObservabilityEvaluation.tsx:83 118 10
parseBIEditorState products/business_intelligence/frontend/biEditorTypes.ts:612 107 10
<anonymous> frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:3910 92 10
createQueryTab frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:4087 82 10
LemonTable frontend/src/lib/lemon-ui/LemonTable/LemonTable.tsx:168 79 10
buildBIQuery products/business_intelligence/frontend/biEditorTypes.ts:1507 65 10
TraceDialogSpanRow products/tracing/frontend/components/TraceDialog/TraceDialogSpanRow.tsx:61 60 10
ReportCardRaw products/signals/frontend/inbox/components/cards/ReportCard.tsx:108 59 10
MetricRowGroup frontend/src/scenes/experiments/MetricsView/new/MetricRowGroup.tsx:545 55 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/infiniteListLogic.ts:1853 48 10
<anonymous> frontend/src/queries/nodes/DataNode/dataNodeLogic.ts:1729 48 10
loadData frontend/src/queries/nodes/DataNode/dataNodeLogic.ts:1098 47 10
InboxDetailFrame products/signals/frontend/inbox/components/detail/ReportDetail.tsx:208 47 10
activate products/signals/frontend/inbox/logics/inboxSetupLogic.ts:1053 47 10
buildBIAnalysisQuery products/business_intelligence/frontend/biAnalysis.ts:180 46 10
TaxonomicFilterMenu frontend/src/lib/components/TaxonomicFilter/menu/TaxonomicFilterMenu.tsx:248 45 10
onFailure frontend/src/initKea.ts:263 44 10
DashboardItems frontend/src/scenes/dashboard/DashboardItems.tsx:99 44 10
getBIDrillSelection products/business_intelligence/frontend/biDrilldown.ts:67 43 10
buildOfflineTrendPanels products/ai_observability/frontend/offline-evaluations/offlineScoreTrends.ts:245 40 10
assertCanvasCapability products/canvas/frontend/host/canvasCapabilities.ts:6 40 10
refreshDashboardItems frontend/src/scenes/dashboard/dashboardLogic.tsx:5301 39 10
watchReasonCopy products/replay_vision/frontend/replay_scanners/components/WatchFeedCard.tsx:63 39 10
<anonymous> products/canvas/frontend/host/canvasHostMessageRouter.ts:104 38 10
DashboardInsightResultMenu products/dashboards/frontend/components/DashboardInsightResultMenu.tsx:23 38 10
loadRemoteItems frontend/src/lib/components/TaxonomicFilter/infiniteListLogic.ts:906 37 10
Exposures frontend/src/scenes/experiments/ExperimentView/Exposures.tsx:131 37 10
PlayerFrameOverlayContent frontend/src/scenes/session-recordings/player/PlayerFrameOverlay.tsx:96 37 10
LemonInputSelect frontend/src/lib/lemon-ui/LemonInputSelect/LemonInputSelect.tsx:182 36 10
<anonymous> frontend/src/lib/lemon-ui/LemonTable/LemonTable.tsx:742 35 10
OfflineItemInspector products/ai_observability/frontend/offline-evaluations/OfflineItemInspector.tsx:16 35 10
<anonymous> frontend/src/queries/nodes/DataNode/dataNodeLogic.ts:998 33 10
WorkflowScene products/workflows/frontend/Workflows/WorkflowScene.tsx:68 33 10
SQLEditorSceneTitle frontend/src/scenes/data-warehouse/editor/SQLEditor.tsx:508 31 10
HogFunctionFilters frontend/src/scenes/hog-functions/filters/HogFunctionFilters.tsx:87 31 10
PersonsModal frontend/src/scenes/trends/persons-modal/PersonsModal.tsx:76 31 10
TracingSceneContents products/tracing/frontend/TracingScene.tsx:87 31 10
<anonymous> frontend/src/lib/lemon-ui/LemonTable/TableRow.tsx:120 30 10
<anonymous> frontend/src/scenes/hog-functions/filters/HogFunctionFilters.tsx:257 30 10
TableRowRaw frontend/src/lib/lemon-ui/LemonTable/TableRow.tsx:33 29 10
loadNextData frontend/src/queries/nodes/DataNode/dataNodeLogic.ts:1316 29 10
OfflineScorerHistory products/ai_observability/frontend/offline-evaluations/OfflineScorerHistory.tsx:26 29 10
<anonymous> products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:2768 29 10
buildTaxonomicGroups frontend/src/lib/components/TaxonomicFilter/utils/buildTaxonomicGroups.tsx:190 28 10
DataCatalogMetricScene products/data_catalog/frontend/DataCatalogMetricScene.tsx:83 28 10
ReportDetail products/signals/frontend/inbox/components/detail/ReportDetail.tsx:664 28 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx:1198 27 10
runQuery frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:2410 27 10
<anonymous> frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:2357 27 10
getBIChartFit products/business_intelligence/frontend/biEditorTypes.ts:481 27 10
ScannerObservationsTable products/replay_vision/frontend/replay_scanners/components/ScannerObservationsTable.tsx:100 27 10
InboxWaitingForWork products/signals/frontend/inbox/components/emptyState/InboxWaitingForWork.tsx:39 27 10
ReportsTab products/signals/frontend/inbox/components/tabs/ReportsTab.tsx:209 27 10
InsightCardInternal frontend/src/lib/components/Cards/InsightCard/InsightCard.tsx:175 26 10
executeQuery frontend/src/queries/query.ts:254 26 10
createTab frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:2166 26 10
<anonymous> frontend/src/scenes/experiments/MetricsView/new/MetricRowGroup.tsx:346 26 10
<anonymous> frontend/src/scenes/experiments/MetricsView/new/MetricRowGroup.tsx:1119 26 10
updateAnimation frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:3549 26 10
parseBIFieldValue products/business_intelligence/frontend/biEditorTypes.ts:573 26 10
AITriageDetails products/conversations/frontend/scenes/ticket/AIPanel.tsx:103 26 10
loadScanner products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:1973 26 10
BroadcastWizard products/workflows/frontend/Broadcasts/BroadcastWizard.tsx:28 26 10
updateCurrentTeam frontend/src/scenes/teamLogic.tsx:428 25 10
ActorRow frontend/src/scenes/trends/persons-modal/PersonsModal.tsx:444 25 10
errors products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:1101 25 10
<anonymous> products/signals/frontend/inbox/utils/inboxSetup.ts:56 25 10
toAudienceFilter products/workflows/frontend/Broadcasts/broadcastAudiencePrefill.ts:74 25 10
launchBroadcast products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1835 25 10
buildRankedResults frontend/src/lib/components/CommandKSearch/commandKRankedResults.ts:166 24 10
getBIFilterSummary products/business_intelligence/frontend/biEditorTypes.ts:1005 24 10
filterExpression products/business_intelligence/frontend/biEditorTypes.ts:1054 24 10
WatchFeedTab products/replay_vision/frontend/replay_scanners/components/WatchFeedTab.tsx:62 24 10
renderTile frontend/src/scenes/dashboard/DashboardItems.tsx:576 23 10
getInsightWithRetry frontend/src/scenes/dashboard/dashboardUtils.ts:444 23 10
captureRenderedScrollSample frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:273 23 10
<anonymous> products/marketing_analytics/frontend/search/SearchPerformanceTab.stories.tsx:241 23 10
TrendsBarChart products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart.tsx:92 23 10
saveEvaluation products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:1378 22 10
<anonymous> products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:1704 22 10
mergeBIChartSettings products/business_intelligence/frontend/biEditorTypes.ts:126 22 10
LineageGraphContent products/data_modeling/frontend/lineage/LineageGraph.tsx:76 22 10
TrendsLineChart products/product_analytics/frontend/insights/trends/TrendsLineChart/TrendsLineChart.tsx:78 22 10
draftScannerFromGoalSuccess products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:2271 22 10
openResolveReportDialog products/signals/frontend/inbox/components/shell/ResolveReportDialog.tsx:48 22 10
SearchAndAiMetricCell products/web_analytics/frontend/searchAndAi/SearchAndAiMetricCell.tsx:34 22 10
<anonymous> products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1255 22 10
fetchAllPendingDefinitions frontend/src/models/propertyDefinitionsModel.ts:443 21 10
saveCohort frontend/src/scenes/cohorts/cohortEditLogic.ts:956 21 10
<anonymous> frontend/src/scenes/dashboard/dashboardLogic.tsx:2325 21 10
saveAsViewSubmit frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:2725 21 10
setOutputType products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:893 21 10
loadScannerEstimate products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:2430 21 10
TraceDrawer products/tracing/frontend/components/TraceDrawer/TraceDrawer.tsx:64 21 10
LegacyEmailSetupModal products/workflows/frontend/Channels/EmailSetup/EmailSetupModal.tsx:37 21 10
handleFetch frontend/src/lib/api.ts:7235 20 10
buildSections frontend/src/lib/components/CommandKSearch/commandKSections.ts:361 20 10
selectItem frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx:2700 20 10
TaxonomicPopover_ frontend/src/lib/components/TaxonomicPopover/TaxonomicPopover.tsx:84 20 10
buildFunnelBreakdownFilter frontend/src/scenes/trends/persons-modal/getPersonsRecordingFilters.ts:15 20 10
getPersonsRecordingFilters frontend/src/scenes/trends/persons-modal/getPersonsRecordingFilters.ts:85 20 10
offlineScoreConfigurationLabel products/ai_observability/frontend/offline-evaluations/offlineScoreTrends.ts:202 20 10
ReportFeedbackFooter products/signals/frontend/inbox/components/detail/ReportFeedbackFooter.tsx:26 20 10
InboxActivationPanel products/signals/frontend/inbox/components/onboarding/InboxActivationPanel.tsx:18 20 10
<anonymous> products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:2219 20 10
<anonymous> frontend/src/queries/nodes/DataNode/dataNodeLogic.ts:2099 19 10
validateGroup frontend/src/scenes/cohorts/cohortUtils.tsx:236 19 10
HogFunctionEventEstimates frontend/src/scenes/hog-functions/metrics/HogFunctionEventEstimates.tsx:18 19 10
syncSnapshotsWithPlayer frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:3177 19 10
recording_domains frontend/src/scenes/team-activity/teamActivityDescriber.tsx:237 19 10
renderContentCard frontend/src/scenes/web-analytics/LiveMetricsDashboard/LiveWebAnalyticsMetrics.tsx:366 19 10
normalizeBIConfig products/business_intelligence/frontend/biEditorTypes.ts:235 19 10
resolveFreePlacementCollisions products/dashboards/frontend/dashboardCustomization.ts:145 19 10
<anonymous> products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:1848 19 10
resolveTaxonomicGroupTypes frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicFilter.ts:205 18 10
<anonymous> frontend/src/lib/lemon-ui/LemonInputSelect/LemonInputSelect.tsx:651 18 10
Table frontend/src/queries/nodes/DataVisualization/Components/Table.tsx:223 18 10
refreshDashboardItem frontend/src/scenes/dashboard/dashboardLogic.tsx:5219 18 10
discardChanges frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:3250 18 10
loadSampleGlobals frontend/src/scenes/hog-functions/configuration/hogFunctionConfigurationLogic.tsx:1175 18 10
<anonymous> frontend/src/scenes/hog-functions/configuration/hogFunctionConfigurationLogic.tsx:1452 18 10
syncPlayerState frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:3039 18 10
numericOutputConfigError products/ai_observability/frontend/evaluations/constants.ts:36 18 10
<anonymous> products/business_intelligence/frontend/biEditorTypes.ts:742 18 10
<anonymous> products/business_intelligence/frontend/biEditorTypes.ts:773 18 10
SearchPerformanceTab products/marketing_analytics/frontend/search/SearchPerformanceTab.tsx:22 18 10
BroadcastContentStep products/workflows/frontend/Broadcasts/steps/BroadcastContentStep.tsx:26 18 10
WorkflowsUtmDefaultsApplyDialog products/workflows/frontend/scenes/settings/WorkflowsUtmDefaultsApplyDialog.tsx:9 18 10
infiniteListResultsReceived frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx:2918 17 10
<anonymous> frontend/src/lib/lemon-ui/LemonInputSelect/LemonInputSelect.tsx:731 17 10
loadPropertyValues frontend/src/models/propertyDefinitionsModel.ts:568 17 10
SQLEditor frontend/src/scenes/data-warehouse/editor/SQLEditor.tsx:116 17 10
SaveAsMetricModal frontend/src/scenes/data-warehouse/editor/SaveAsMetricModal.tsx:34 17 10
<anonymous> frontend/src/scenes/experiments/MetricsView/new/MetricRowGroup.tsx:189 17 10
<anonymous> frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:4039 17 10
<anonymous> products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:1767 17 10
<anonymous> products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:1875 17 10
EvaluationOverviewResults products/ai_observability/frontend/evaluations/overview/EvaluationOverviewResults.tsx:79 17 10
groupingSets products/business_intelligence/frontend/biAnalysis.ts:136 17 10
describeSearch products/business_knowledge/frontend/scenes/playground/playgroundDisplay.ts:97 17 10
ComposerRoot products/posthog_ai/frontend/components/composer/Composer.tsx:86 17 10
verificationStepsOf products/workflows/frontend/Channels/EmailDomain/emailDomainLogic.ts:80 17 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicFilter.ts:481 16 10
<anonymous> frontend/src/lib/lemon-ui/LemonInputSelect/LemonInputSelect.tsx:340 16 10
ApprovalDetail frontend/src/scenes/approvals/ApprovalDetail.tsx:37 16 10
copyToDashboard frontend/src/scenes/dashboard/dashboardLogic.tsx:2518 16 10
persistEditorDraft frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:1923 16 10
updateInsight frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:3166 16 10
<anonymous> frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:4469 16 10
setCurrentSegment frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:2973 16 10
loadOverview frontend/src/scenes/web-analytics/pagePerformanceLogic.ts:1167 16 10
loadEvaluation products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:1220 16 10
EvaluationDrawerEmptyState products/ai_observability/frontend/evaluations/overview/EvaluationDrawerEmptyState.tsx:28 16 10
isBIAnalysisConfig products/business_intelligence/frontend/biAnalysis.ts:33 16 10
calculationExpression products/business_intelligence/frontend/biAnalysis.ts:93 16 10
snapBetweenAdjacentTiles products/dashboards/frontend/dashboardCustomization.ts:77 16 10
<anonymous> products/replay_vision/frontend/components/RecordingTimeline.tsx:83 16 10
loadScoutRunCosts products/signals/frontend/inbox/logics/scoutFleetLogic.ts:1083 16 10
applyFromUrl products/signals/frontend/inbox/logics/scoutFleetLogic.ts:2142 16 10
SpanInspector products/tracing/frontend/components/SpanInspector/SpanInspector.tsx:57 16 10
buildTraceDialogRows products/tracing/frontend/components/TraceDialog/traceDialogRows.ts:158 16 10
NotificationRow frontend/src/lib/components/NotificationsMenu/NotificationRow.tsx:147 15 10
setCriteria frontend/src/scenes/cohorts/cohortEditLogic.ts:1175 15 10
<anonymous> frontend/src/scenes/cohorts/cohortUtils.tsx:471 15 10
<anonymous> frontend/src/scenes/cohorts/cohortUtils.tsx:713 15 10
updateWidgetTile frontend/src/scenes/dashboard/dashboardLogic.tsx:2598 15 10
ApprovalPolicyModal frontend/src/scenes/settings/organization/Approvals/ApprovalPolicies.tsx:210 15 10
testHogOnSample products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:720 15 10
EvaluationDetailResults products/ai_observability/frontend/evaluations/overview/EvaluationDetailResults.tsx:13 15 10
watchCardHeadline products/replay_vision/frontend/replay_scanners/components/WatchFeedCard.tsx:198 15 10
FirstReportProgress products/signals/frontend/inbox/components/emptyState/FirstReportProgress.tsx:35 15 10
openDismissReportDialog products/signals/frontend/inbox/components/shell/DismissReportDialog.tsx:44 15 10
updateScoutConfig products/signals/frontend/inbox/logics/scoutFleetLogic.ts:1888 15 10
TodayShell frontend/src/layout/today/TodayShell.tsx:43 14 10
listLegacy frontend/src/lib/api.ts:2573 14 10
<anonymous> frontend/src/lib/components/Cards/InsightCard/InsightCard.tsx:327 14 10
CommandKSearchRankedItem frontend/src/lib/components/CommandKSearch/CommandKSearchRankedItem.tsx:32 14 10
openRow frontend/src/lib/components/CommandKSearch/commandKSearchLogic.tsx:786 14 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/utils/suggestedContextFilters.ts:31 14 10
resolveCurrencyFormat frontend/src/lib/utils/liquid.ts:51 14 10
diffVersions frontend/src/lib/utils/semver.ts:68 14 10
render frontend/src/queries/nodes/DataVisualization/Components/Table.tsx:380 14 10
performQuery frontend/src/queries/query.ts:402 14 10
classifyQueryVizCanvas frontend/src/queries/utils.ts:535 14 10
setLatestVersionsOnQuery frontend/src/queries/utils.ts:1143 14 10
PolicyConfigurationDisplay frontend/src/scenes/approvals/ApprovalDetail.tsx:369 14 10
<anonymous> frontend/src/scenes/experiments/ExperimentWizard/experimentWizardLogic.ts:316 14 10
<anonymous> frontend/src/scenes/hog-functions/configuration/hogFunctionConfigurationLogic.tsx:1644 14 10
getPreposition frontend/src/scenes/surveys/surveyActivityDescriber.tsx:451 14 10
session_recording_masking_config frontend/src/scenes/team-activity/teamActivityDescriber.tsx:292 14 10
evaluationRunsFilterHogQL products/ai_observability/frontend/evaluations/constants.ts:161 14 10
BIDrilldownModal products/business_intelligence/frontend/BIDrilldownModal.tsx:14 14 10
BIScatterGraph products/business_intelligence/frontend/BIScatterGraph.tsx:24 14 10
getBIDrillQueries products/business_intelligence/frontend/biDrilldown.ts:191 14 10
PlaygroundTurn products/business_knowledge/frontend/scenes/playground/PlaygroundTurn.tsx:17 14 10
ask products/business_knowledge/frontend/scenes/playground/businessKnowledgePlaygroundLogic.ts:419 14 10
handle products/canvas/frontend/host/canvasDataBridge.ts:175 14 10
SqlTestResult products/data_catalog/frontend/components/SqlTestResult.tsx:23 14 10
ErrorTrackingIssueScene products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene.tsx:78 14 10
searchTableStatus products/marketing_analytics/frontend/search/searchPerformance.ts:25 14 10
ReplayScannersScene products/replay_vision/frontend/replay_scanners/ReplayScannersScene.tsx:173 14 10
deleteScout products/signals/frontend/inbox/logics/scoutFleetLogic.ts:1952 14 10
collapseSelectedSpan products/tracing/frontend/components/TraceView/traceViewLogic.ts:782 14 10
CertificationSuggestionRow products/warehouse_suggestions/frontend/components/CertificationSuggestionRow.tsx:27 14 10
setEmail products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1615 14 10
computeConditionalFormattingBackground frontend/src/queries/nodes/DataVisualization/Components/Table.tsx:276 13 10
determineFilterType frontend/src/scenes/cohorts/cohortUtils.tsx:557 13 10
setDashboardEditing frontend/src/scenes/dashboard/dashboardLogic.tsx:5971 13 10
renderQueryOutline frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:188 13 10
<anonymous> frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:3703 13 10
computeRenderability frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:2211 13 10
loadActors frontend/src/scenes/trends/persons-modal/personsModalLogic.ts:258 13 10
groupPageReportTiles frontend/src/scenes/web-analytics/pageReportsLogic.ts:93 13 10
<anonymous> products/canvas/frontend/host/canvasDataBridge.ts:251 13 10
IdentityVerificationSecretSection products/conversations/frontend/scenes/settings/IdentityVerificationSecretSection.tsx:16 13 10
MetricFromInsightModal products/data_catalog/frontend/components/MetricFromInsightModal.tsx:26 13 10
RetentionLineChart products/product_analytics/frontend/insights/retention/RetentionLineChart/RetentionLineChart.tsx:61 13 10
observationFilterParams products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:337 13 10
submit products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:1152 13 10
loadMoreFeed products/replay_vision/frontend/replay_scanners/watchFeedLogic.ts:273 13 10
SearchResults products/replay_vision/frontend/search/SearchResults.tsx:336 13 10
captureScoutConfigUpdates products/signals/frontend/inbox/logics/scoutFleetLogic.ts:127 13 10
DeltaPct products/tracing/frontend/TraceCompareFlame.tsx:187 13 10
FlameRow products/tracing/frontend/TraceCompareFlame.tsx:280 13 10
keepSelectionOnScreen products/tracing/frontend/components/TraceView/traceViewLogic.ts:889 13 10
ContentAutopilotPrompts products/web_analytics/frontend/contentAutopilot/ContentAutopilotPrompts.tsx:34 13 10
resolvePagePerformanceWindow products/web_analytics/frontend/searchAndAi/searchAndAiQueries.ts:54 13 10
getStickyColumnInfo frontend/src/lib/lemon-ui/LemonTable/columnLayoutUtils.ts:37 12 10
insightNew frontend/src/products.tsx:1809 12 10
SqlPieGraph frontend/src/queries/nodes/DataVisualization/Components/Charts/SqlPieGraph.tsx:24 12 10
pollForResults frontend/src/queries/query.ts:202 12 10
shouldQueryBeAsync frontend/src/queries/utils.ts:432 12 10
isRecentPersonFilterUnsupported frontend/src/scenes/cohorts/cohortUtils.tsx:819 12 10
renderSectionGrid frontend/src/scenes/dashboard/DashboardItems.tsx:771 12 10
FeatureFlagRulesV2Editor frontend/src/scenes/feature-flags/FeatureFlagRulesV2Editor.tsx:31 12 10
getPlayerFrameLoadDiagnostics frontend/src/scenes/session-recordings/player/playerFrameLoadDiagnostics.ts:54 12 10
readRenderedScroll frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:221 12 10
describeFieldChange frontend/src/scenes/surveys/surveyActivityDescriber.tsx:617 12 10
parsePagePerformanceOverviewResponse frontend/src/scenes/web-analytics/pagePerformanceLogic.ts:256 12 10
<anonymous> products/ai_observability/frontend/evaluations/llmEvaluationLogic.ts:1552 12 10
EvaluationResultCards products/ai_observability/frontend/evaluations/overview/EvaluationResultCards.tsx:35 12 10
overviewPeriod products/ai_observability/frontend/evaluations/overview/evaluationsOverviewLogic.ts:136 12 10
<anonymous> products/ai_observability/frontend/offline-evaluations/OfflineScoreTrendChart.tsx:116 12 10
<anonymous> products/ai_observability/frontend/offline-evaluations/OfflineScoreTrendChart.tsx:83 12 10
getBIEffectiveQuery products/business_intelligence/frontend/biDrilldown.ts:33 12 10
getBIFilterValidationError products/business_intelligence/frontend/biEditorTypes.ts:981 12 10
MetricNameField products/data_catalog/frontend/components/MetricNameField.tsx:26 12 10
<anonymous> products/data_modeling/frontend/lineage/LineageGraph.tsx:247 12 10
RetentionContainer products/product_analytics/frontend/insights/retention/RetentionContainer.tsx:17 12 10
WatchFeedRow products/replay_vision/frontend/replay_scanners/components/WatchFeedCard.tsx:386 12 10
<anonymous> products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:1723 12 10
changedRefreshOptions products/warehouse_suggestions/frontend/warehouseSuggestionsLogic.ts:138 12 10
PageDirectoryMetricCell products/web_analytics/frontend/pageReports/PageDirectoryMetricCell.tsx:19 12 10
loadAiEmailDraftSuccess products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1460 12 10
openInWorkflowEditorConfirmed products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:2053 12 10
getBroadcastStatus products/workflows/frontend/Broadcasts/broadcastsLogic.ts:146 12 10
phaseOf products/workflows/frontend/Channels/EmailDomain/emailDomainLogic.ts:44 12 10
loadStatusSuccess products/workflows/frontend/Channels/EmailDomain/emailDomainStatusLogic.ts:280 12 10
createSender products/workflows/frontend/Channels/EmailDomain/emailDomainWizardLogic.ts:259 12 10
sessionPreview frontend/src/layout/today/todayPreviewCards.ts:75 11 10
syncRemote frontend/src/lib/components/CommandKSearch/commandKSearchLogic.tsx:817 11 10
applyKeyIntent frontend/src/lib/components/CommandKSearch/commandKSearchLogic.tsx:954 11 10
lowerSections frontend/src/lib/components/CommandKSearch/commandKSections.ts:305 11 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicGroupsContext.ts:112 11 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/menu/TaxonomicFilterMenu.tsx:285 11 10
<anonymous> frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx:2510 11 10
DraggableValueSnack frontend/src/lib/lemon-ui/LemonInputSelect/LemonInputSelect.tsx:1115 11 10
<anonymous> frontend/src/lib/lemon-ui/LemonInputSelect/LemonInputSelect.tsx:1226 11 10
constructValuesEndpoint frontend/src/models/propertyDefinitionsModel.ts:157 11 10
loadNewData frontend/src/queries/nodes/DataNode/dataNodeLogic.ts:1279 11 10
compareTableCells frontend/src/queries/nodes/DataVisualization/Components/Table.tsx:70 11 10
getMathTypeWarning frontend/src/queries/utils.ts:1112 11 10
submit frontend/src/scenes/cohorts/cohortEditLogic.ts:886 11 10
<anonymous> frontend/src/scenes/cohorts/cohortUtils.tsx:319 11 10
onChangedCustomization frontend/src/scenes/dashboard/dashboardActivityDescriber.tsx:155 11 10
moveToDashboardSuccess frontend/src/scenes/dashboard/dashboardLogic.tsx:5018 11 10
saveEditModeChangesSuccess frontend/src/scenes/dashboard/dashboardLogic.tsx:5850 11 10
<anonymous> frontend/src/scenes/dashboard/dashboardLogic.tsx:6681 11 10
getDashboardTileDisplayName frontend/src/scenes/dashboard/dashboardUtils.ts:152 11 10
getTabHash frontend/src/scenes/data-warehouse/editor/sqlEditorLogic.tsx:499 11 10
findSegmentForTimestamp frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:516 11 10
<anonymous> frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:2051 11 10
<anonymous> frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts:4122 11 10
onTargetingFlag frontend/src/scenes/surveys/surveyActivityDescriber.tsx:287 11 10
feature_flag_policy_config frontend/src/scenes/team-activity/teamActivityDescriber.tsx:490 11 10
WebTabs frontend/src/scenes/web-analytics/WebAnalyticsDashboard.tsx:452 11 10
resolvePagePerformanceDataState frontend/src/scenes/web-analytics/pagePerformanceLogic.ts:215 11 10
EvaluationCompareItem products/ai_observability/frontend/evaluations/overview/EvaluationCompareItem.tsx:34 11 10
<anonymous> products/ai_observability/frontend/evaluations/overview/evaluationDetailResultsLogic.ts:467 11 10
readFilters products/ai_observability/frontend/offline-evaluations/offlineScorerHistoryLogic.ts:82 11 10
BIAnalysisControls products/business_intelligence/frontend/BIAnalysisControls.tsx:13 11 10
isBITableCalculation products/business_intelligence/frontend/biAnalysis.ts:19 11 10
getBIChartRecord products/business_intelligence/frontend/biDrilldown.ts:157 11 10
BusinessKnowledgeScene products/business_knowledge/frontend/scenes/sources/BusinessKnowledgeScene.tsx:47 11 10
query products/canvas/frontend/host/canvasDataBridge.ts:207 11 10
RightHandColumn products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene.tsx:324 11 10
ObservationThumbnail products/replay_vision/frontend/components/ObservationThumbnail.tsx:25 11 10
ScannerPromptField products/replay_vision/frontend/replay_scanners/components/ScannerTypeConfigEditor.tsx:36 11 10
loadObservations products/replay_vision/frontend/replay_scanners/replayScannerLogic.ts:2631 11 10
WatchLink products/replay_vision/frontend/search/SearchResults.tsx:60 11 10
revealSpanInRows products/tracing/frontend/components/TraceDialog/traceDialogRows.ts:407 11 10
onKeyDown products/tracing/frontend/components/TraceView/traceViewLogic.ts:663 11 10
buildSpanTree products/tracing/frontend/spanTree.ts:76 11 10
<anonymous> products/warehouse_suggestions/frontend/warehouseSuggestionsLogic.ts:670 11 10
loadPreviousSend products/workflows/frontend/Broadcasts/broadcastPreviousSendLogic.ts:100 11 10
saveName products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:1677 11 10
moveToDraft products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:2008 11 10
saveDraftSchedule products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts:2296 11 10
<anonymous> products/workflows/frontend/Broadcasts/broadcastsLogic.ts:486 11 10
<anonymous> products/workflows/frontend/Broadcasts/broadcastsLogic.ts:600 11 10
<anonymous> products/workflows/frontend/Channels/EmailDomain/components/StepIndicator.tsx:17 11 10
Heading products/workflows/frontend/Channels/EmailDomain/steps/VerifyingStep.tsx:20 11 10
startSuggestion products/workflows/frontend/setupGuide/suggestions/workflowDataSuggestionsLogic.ts:251 11 10
✅ Comment density — 0% of added code lines are comments (0 of 79)

This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.

Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.

This check does not block merging. It updates on every push and clears when the share drops.

⚠️ Bundle size — 🔺 +314.9 KiB (+0.4%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 76.91 MiB · 🔺 +314.9 KiB (+0.4%)

File Size Δ vs base
render-query/src/render-query/render-query.js 24.89 MiB 🔺 +163.0 KiB (+0.6%)
posthog-app/src/scenes/web-analytics/WebAnalyticsScene.js 237.4 KiB 🔺 +23.8 KiB (+11.1%)
posthog-app/_parent/products/data_catalog/frontend/DataCatalogNewMetricScene.js 19.4 KiB 🔺 +19.4 KiB (new)
posthog-app/_parent/products/apm/frontend/ApplicationObservabilityScene.js 11.8 KiB 🔺 +11.8 KiB (new)
exporter/src/exporter/scenes/ExporterNotebookScene.js 3.90 MiB 🔺 +11.4 KiB (+0.3%)
posthog-app/_parent/products/ai_observability/frontend/evaluations/EvaluationsScene.js 73.9 KiB 🟢 -10.7 KiB (-12.6%)
posthog-app/_parent/products/tracing/frontend/TracingScene.js 161.9 KiB 🟢 -9.5 KiB (-5.6%)
posthog-app/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation.js 113.1 KiB 🔺 +9.1 KiB (+8.8%)
posthog-app/_parent/products/business_knowledge/frontend/scenes/playground/BusinessKnowledgePlaygroundScene.js 31.0 KiB 🔺 +8.9 KiB (+40.2%)
posthog-app/_parent/products/workflows/frontend/Channels/EmailDomain/EmailDomainScene.js 8.1 KiB 🔺 +8.1 KiB (new)
posthog-app/src/scenes/feature-flags/FeatureFlag.js 153.7 KiB 🔺 +8.0 KiB (+5.5%)
exporter/src/queries/schema.js 1.27 MiB 🔺 +7.4 KiB (+0.6%)
posthog-app/src/queries/schema.js 1.27 MiB 🔺 +7.4 KiB (+0.6%)
posthog-app/_parent/products/billing_alerts/frontend/BillingAlerts.js 29.3 KiB 🔺 +3.9 KiB (+15.5%)
exporter/src/scenes/web-analytics/WebAnalyticsInsight.js 53.7 KiB 🔺 +3.6 KiB (+7.1%)
posthog-app/src/layout/navigation-3000/sidepanel/panels/discussion/SidePanelDiscussion.js 8.3 KiB 🔺 +3.2 KiB (+63.9%)
posthog-app/src/scenes/experiments/Experiment.js 409.9 KiB 🔺 +2.6 KiB (+0.6%)
posthog-app/_parent/products/data_catalog/frontend/DataCatalogScene.js 36.9 KiB 🟢 -2.5 KiB (-6.3%)
posthog-app/_parent/products/signals/frontend/inbox/InboxScene.js 512.2 KiB 🔺 +2.3 KiB (+0.5%)
posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene.js 108.2 KiB 🔺 +2.2 KiB (+2.1%)
posthog-app/_parent/products/workflows/frontend/Broadcasts/BroadcastScene.js 122.2 KiB 🔺 +2.2 KiB (+1.8%)
posthog-app/src/layout/today/TodayAnalyticsSidebar.js 7.8 KiB 🔺 +2.1 KiB (+37.0%)
posthog-app/src/scenes/onboarding/Onboarding.js 783.3 KiB 🔺 +2.1 KiB (+0.3%)
posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ScannerEditorScene.js 82.1 KiB 🟢 -1.7 KiB (-2.0%)
posthog-app/_parent/products/ai_observability/frontend/offline-evaluations/OfflineScorerHistoryScene.js 19.5 KiB 🔺 +1.3 KiB (+7.2%)
posthog-app/_parent/products/alerts/frontend/views/EditAlertModal.js 7.2 KiB 🔺 +1.3 KiB (+21.3%)
posthog-app/_parent/products/alerts/frontend/views/InsightAlerts.js 16.1 KiB 🔺 +1.3 KiB (+8.5%)
posthog-app/_parent/products/logs/frontend/components/LogsAlerting/LogsAlertingSection.js 7.6 KiB 🔺 +1.2 KiB (+18.8%)
posthog-app/src/lib/components/ActivityLog/describers.js 175.1 KiB 🔺 +1.2 KiB (+0.7%)
exporter/src/lib/components/ActivityLog/describers.js 174.5 KiB 🔺 +1.2 KiB (+0.7%)
posthog-app/src/scenes/AuthenticatedShell.js 271.1 KiB 🔺 +1.2 KiB (+0.4%)

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

✅ Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1022.7 KiB · 24 files 🔺 +3.4 KiB (+0.3%) █████████░ 87.3% of 1.14 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
2.96 MiB · 620 files 🔺 +9.2 KiB (+0.3%) ██████████ 97.7% of 3.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.47 MiB · 2,558 files 🔺 +40.3 KiB (+0.5%) ██████████ 99.7% of 7.50 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
9.93 MiB · 3,725 files 🔺 +35.9 KiB (+0.4%) ██████████ 99.1% of 10.01 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
7.65 MiB · 2,651 files 🔺 +43.2 KiB (+0.6%) ██████████ 98.9% of 7.74 MiB
AI-first home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
7.90 MiB · 2,643 files 🔺 +41.7 KiB (+0.5%) ██████████ 99.9% of 7.91 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
9.37 MiB · 3,508 files 🔺 +29.8 KiB (+0.3%) ██████████ 97.7% of 9.59 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
10.30 MiB · 3,755 files 🔺 +57.9 KiB (+0.6%) ██████████ 95.1% of 10.83 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
8.40 MiB · 3,087 files 🔺 +23.2 KiB (+0.3%) █████████░ 88.7% of 9.47 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/zod/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/billing/billingLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/ProductEmptyState/productSetupPreloadLogic.ts stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/wizard/frontend/runs/WizardRunDetailsDrawer.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayShell.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayContextPanelFloating.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodaySidePanel.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayTopBar.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/todayRailItems.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/validators.js stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 packages/quill/packages/charts/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/RecordingsWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/api/primitives.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/scenes/notebooks/Notebook/notebookLogic.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/LiveMetricsDashboard/LiveWebAnalyticsMetrics.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 products/product_analytics/frontend/insights/trends/WorldMap/countryVectors.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/scenes/settings/SettingsMap.tsx stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 @jspm/core/nodelibs/browser/fs stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.7 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
4.0 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.7 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.6 KiB src/lib/utils/bootTiming.ts
1.6 KiB src/index.tsx
1.2 KiB src/RootErrorBoundary.tsx
949 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
86.1 KiB src/lib/api.ts
68.2 KiB src/lib/lemon-ui/icons/icons.tsx
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
27.0 KiB ../node_modules/.pnpm/tailwind-merge@2.2.2/node_modules/tailwind-merge/dist/bundle-mjs.mjs
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
86.1 KiB src/lib/api.ts
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
86.1 KiB src/lib/api.ts
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
182.9 KiB src/queries/validators.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
322.9 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
316.1 KiB ../node_modules/.pnpm/posthog-js@1.438.23_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
286.4 KiB src/taxonomy/core-filter-definitions-by-group.json
239.9 KiB ../packages/quill/packages/quill/dist/index.js
217.5 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.8 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
100.8 KiB src/products.tsx
94.5 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.5 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of PostHog#32479

✅ Toolbar bundle — eager 2.29 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.29 MiB · 18 files 🔺 +5.0 KiB (+0.2%) ████░░░░░░ 40.1% of 5.72 MiB
Deferred (lazy) 2.11 MiB · 40 files 🔺 +552 B (+0.0%) n/a — loads on demand
Loader dist/toolbar.js 1.2 KiB no change █░░░░░░░░░ 6.0% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
905.2 KiB dist/toolbar/toolbar-app-S6AJRJV7.css
694.9 KiB dist/toolbar/chunk-chunk-6MTPPF75.js
259.9 KiB dist/toolbar/chunk-chunk-ONRHJSKR.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
130.4 KiB dist/toolbar/chunk-chunk-SFCUI5FH.js
74.8 KiB dist/toolbar/toolbar-app-N45GYVDW.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-REHHFROD.js
21.7 KiB dist/toolbar/chunk-chunk-C4XR7ZDA.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

✅ Dist folder size — 🔺 +4.49 MiB (+0.5%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 969.30 MiB · 🔺 +4.49 MiB (+0.5%)

ℹ️ MCP UI apps size — 34 app(s), 27969.1 KB JS

Built size of each MCP UI app (main.js + styles.css).

App JS CSS
debug 844.3 KB 209.1 KB
action 767.7 KB 209.1 KB
action-list 835.3 KB 209.1 KB
cohort 766.7 KB 209.1 KB
cohort-list 834.3 KB 209.1 KB
email-template 766.6 KB 209.1 KB
error-details 771.6 KB 209.1 KB
error-issue 768.9 KB 209.1 KB
error-issue-list 836.7 KB 209.1 KB
experiment 832.4 KB 209.1 KB
experiment-list 836.1 KB 209.1 KB
experiment-results 834.9 KB 209.1 KB
feature-flag 834.7 KB 209.1 KB
feature-flag-list 838.4 KB 209.1 KB
feature-flag-testing 770.0 KB 209.1 KB
inline-scan 767.2 KB 209.1 KB
insight-actors 833.8 KB 209.1 KB
llm-costs 831.1 KB 209.1 KB
session-recording 768.9 KB 209.1 KB
survey 768.3 KB 209.1 KB
survey-global-stats 831.1 KB 209.1 KB
survey-list 836.0 KB 209.1 KB
survey-stats 831.1 KB 209.1 KB
trace-span 767.1 KB 209.1 KB
trace-span-list 835.2 KB 209.1 KB
vision-observation-list 834.4 KB 209.1 KB
workflow 767.0 KB 209.1 KB
workflow-list 834.7 KB 209.1 KB
workflow-setup-status 766.7 KB 209.1 KB
query-results 1086.5 KB 209.1 KB
render-ui 1162.4 KB 209.1 KB
visual-review-snapshots 771.6 KB 209.1 KB
workflow-data-suggestions 769.4 KB 209.1 KB
workflow-sending-rules 768.0 KB 209.1 KB
ℹ️ MCP agent API — agent-facing tool changes

What this PR changes for agents, from the tool schema snapshots and tool definitions.

Tools added (13): anomaly-insight-get (952 chars), anomaly-search (1,265 chars), inbox-reviewer-exclusions-create (605 chars), inbox-reviewer-exclusions-get (147 chars), inbox-reviewer-exclusions-list (33 chars), inbox-reviewer-exclusions-revoke (147 chars), inbox-reviewer-exclusions-update (512 chars), integrations-email-status-retrieve, integrations-email-verify-create, message-categories-create (1,184 chars), message-categories-get (138 chars), message-categories-list (207 chars), message-categories-update (1,014 chars)
Tools removed (1): vision-scanners-suggest-tags

Tools changed (57):

Tool Params Scopes Annotations Schema chars
batch-export-create 28,053 -> 27,660
batch-export-update 27,812 -> 27,419
broadcasts-create +source_record 19,354 -> 19,647
canvas-draft-create 5,868 -> 6,170
canvas-edit-create description changed 4,975 -> 5,277
canvas-layout-patch description changed
canvas-layout-publish description changed
canvas-publish-create description changed 6,349 -> 6,651
canvas-validate-create 5,738 -> 6,040
cohorts-add-persons-to-static-cohort-partial-update description changed 251 -> 343
conversations-tickets-list 3,871 -> 3,923
conversations-views-create 4,891 -> 5,095
conversations-views-update 5,011 -> 5,215
create-feature-flag schema changed
dashboard-create +group_display description changed 4,456 -> 4,743
dashboard-create-tile description changed
dashboard-reorder-tiles description changed
dashboard-update +group_display description changed 8,441 -> 8,728
dashboard-update-text-tile description changed
dashboard-widgets-batch-add description changed
dashboard-widgets-batch-update description changed
data-catalog-metric-approve-prepare +expected_updated_at 77 -> 650
data-catalog-metric-create +owner 2,245 -> 2,654
data-catalog-metric-update +owner description changed 2,054 -> 2,463
data-quality-subjects +include_columns +limit +offset +search +subject_type description changed 33 -> 1,025
error-tracking-settings-get description changed
error-tracking-settings-update +ingestion_enabled description changed 822 -> 1,058
experiment-holdouts-create schema changed
experiment-holdouts-partial-update schema changed
file-download-batch-exports-count-rows-create 12,599 -> 12,206
file-download-batch-exports-create 19,115 -> 18,722
generate-app-url 10,663 -> 10,749
inbox-report-actions-list description changed
inbox-report-actions-run +message description changed 570 -> 1,122
inbox-reports-list description changed 8,912 -> 8,837
insight-update description changed
llma-offline-experiment-upload 4,473 -> 4,648
llma-offline-scorer-history +breakdown 3,142 -> 3,544
notebook-edit description changed
notebooks-add-cell description changed

...and 17 more changed tools.

Silthus and others added 2 commits October 27, 2026 05:39
SES requires a non-ASCII display name in From and To as an RFC 2047
encoded word, so "Café Müller" went out as raw UTF-8. formatMailbox now
encodes such names and keeps the quoted string for ASCII names. Sender
name overrides keep quotes, angle brackets and backslashes inside the
escaped name instead of stripping them. The maildev path hands
nodemailer a structured address, because nodemailer would quote an
encoded word as literal text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nodemailer's encodeWord splits a long name on UTF-16 units and keeps
surrogate pairs whole only in the emoji range, so a name with a
character such as U+20BB7 decoded with replacement characters. The
email service now builds the encoded words itself and splits only
between code points, at most 45 bytes per word.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Silthus
Silthus force-pushed the fix/email-from-name-encoding branch from fd42eee to 3ace43f Compare October 27, 2026 05:39
Replace the explanatory comments with named constants for the RFC 2047
word layout and the printable-ASCII check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant