Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add MCP tools that create an email sender, check Domain Connect support, build a Domain Connect apply URL and update a sender, with typed request schemas for their endpoints and scoped API key and OAuth access behind the workflows-email-from-code flag. Point the tools at the email status and verify tools master added, and add the setting-up-an-email-domain skill and its eval suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Absorb #352: the update tests for OAuth tokens, an unresolved flag and the access restrictions that the other sender tests do not cover, now on workflows-email-from-code, and the guide section on scoped sender access. Verify keeps master's scoped access. (cherry picked from commit 8064a1f) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ation The event took its organization group from the acting user's current organization, so a verification in another organization's project landed on the wrong group. Pass the sender's organization, on both the verify and the Domain Connect paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nner Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e057075 to
7386a38
Compare
🤖 CI report✅ Complexity (TypeScript) — cleanCyclomatic 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.
|
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.02 MiB · 25 files | 🔺 +133 B (+0.0%) | █████████░ 88.8% 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.99 MiB · 622 files | 🔺 +115 B (+0.0%) | ██████████ 98.5% of 3.03 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
6.46 MiB · 2,235 files | 🟢 -243 B (-0.0%) | ██████████ 95.4% of 6.77 MiB |
dashboard scenesrc/scenes/dashboard/Dashboard.tsx |
9.97 MiB · 3,730 files | 🔺 +1.8 KiB (+0.0%) | ██████████ 99.6% of 10.01 MiB |
today home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx |
6.71 MiB · 2,337 files | 🟢 -243 B (-0.0%) | ██████████ 96.4% of 6.96 MiB |
AI-first home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx |
7.28 MiB · 2,426 files | 🟢 -243 B (-0.0%) | ██████████ 96.7% of 7.53 MiB |
events scenesrc/scenes/activity/explore/EventsScene.tsx |
9.40 MiB · 3,502 files | 🔺 +1.8 KiB (+0.0%) | ██████████ 98.0% of 9.59 MiB |
web analytics scenesrc/scenes/web-analytics/WebAnalyticsScene.tsx |
10.36 MiB · 3,769 files | 🔺 +1.8 KiB (+0.0%) | ██████████ 95.6% of 10.83 MiB |
replay detail scenesrc/scenes/session-recordings/detail/SessionRecordingDetail.tsx |
7.99 MiB · 2,970 files | 🔺 +1.8 KiB (+0.0%) | ████████░░ 84.4% 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 | src/index.tsx |
| 1.7 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.7 KiB | src/lib/utils/bootTiming.ts |
| 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 KiB | src/products.tsx |
| 86.6 KiB | src/lib/api.ts |
| 67.9 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 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.6 KiB | src/lib/api.ts |
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
| Size | File |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 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.6 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 187.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 |
| 102.9 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 |
|---|---|
| 325.0 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 316.5 KiB | ../node_modules/.pnpm/posthog-js@1.443.0_@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 |
| 102.9 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.33 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.33 MiB · 19 files | 🔺 +115 B (+0.0%) | ████░░░░░░ 40.8% of 5.72 MiB |
| Deferred (lazy) | 2.11 MiB · 42 files | no change | 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 |
|---|---|
| 941.8 KiB | dist/toolbar/toolbar-app-CNZCJTDY.css |
| 695.8 KiB | dist/toolbar/chunk-chunk-NUWPCNXY.js |
| 261.2 KiB | dist/toolbar/chunk-chunk-T5DKNJQU.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 130.4 KiB | dist/toolbar/chunk-chunk-KDUJEIKP.js |
| 75.7 KiB | dist/toolbar/toolbar-app-TP2JYJFO.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 33.8 KiB | dist/toolbar/chunk-chunk-FR2SFTP5.js |
| 21.7 KiB | dist/toolbar/chunk-chunk-2P7IMPQ2.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 — 🔺 +26.3 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 966.36 MiB · 🔺 +26.3 KiB (+0.0%)
ℹ️ MCP UI apps size — 35 app(s), 29120.9 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 844.3 KB | 211.6 KB |
| explain-chart | 1117.7 KB | 211.6 KB |
| action | 767.7 KB | 211.6 KB |
| action-list | 835.3 KB | 211.6 KB |
| cohort | 766.7 KB | 211.6 KB |
| cohort-list | 834.3 KB | 211.6 KB |
| email-template | 766.6 KB | 211.6 KB |
| error-details | 771.6 KB | 211.6 KB |
| error-issue | 768.9 KB | 211.6 KB |
| error-issue-list | 836.8 KB | 211.6 KB |
| experiment | 832.4 KB | 211.6 KB |
| experiment-list | 836.1 KB | 211.6 KB |
| experiment-results | 834.3 KB | 211.6 KB |
| feature-flag | 834.7 KB | 211.6 KB |
| feature-flag-list | 838.4 KB | 211.6 KB |
| feature-flag-testing | 770.0 KB | 211.6 KB |
| inline-scan | 767.2 KB | 211.6 KB |
| insight-actors | 833.8 KB | 211.6 KB |
| llm-costs | 831.1 KB | 211.6 KB |
| session-recording | 769.0 KB | 211.6 KB |
| survey | 768.3 KB | 211.6 KB |
| survey-global-stats | 831.1 KB | 211.6 KB |
| survey-list | 836.0 KB | 211.6 KB |
| survey-stats | 831.1 KB | 211.6 KB |
| trace-span | 767.1 KB | 211.6 KB |
| trace-span-list | 835.2 KB | 211.6 KB |
| vision-observation-list | 834.4 KB | 211.6 KB |
| workflow | 767.1 KB | 211.6 KB |
| workflow-list | 834.7 KB | 211.6 KB |
| workflow-setup-status | 766.7 KB | 211.6 KB |
| query-results | 1089.6 KB | 211.6 KB |
| render-ui | 1193.6 KB | 211.6 KB |
| visual-review-snapshots | 771.6 KB | 211.6 KB |
| workflow-data-suggestions | 769.4 KB | 211.6 KB |
| workflow-sending-rules | 768.1 KB | 211.6 KB |
ℹ️ MCP agent API — agent-facing tool changes
What this PR changes for agents, from the tool schema snapshots and tool definitions.
Tools added (4): integrations-domain-connect-apply-url-create (431 chars), integrations-domain-connect-check-retrieve (435 chars), integrations-email-create (1,388 chars), integrations-email-partial-update (1,747 chars)
Tools changed (2):
| Tool | Params | Scopes | Annotations | Schema chars |
|---|---|---|---|---|
integrations-email-status-retrieve |
+id +refresh |
n/a -> 298 | ||
integrations-email-verify-create |
+id |
n/a -> 142 |
ℹ️ frontend-layers — no base comparison available
Static imports from a lower frontend layer into a higher one (layers, lowest first: kernel, shell, query, features). Compared with the base branch, so an import that a PR also adds to layer-baseline.txt still shows here. Sizes are the source bytes on the eager path of every logged-in page.
| Layer | Eager source bytes | Δ vs base |
|---|---|---|
| kernel | 4.06 MiB | (no base measurement) |
| shell | 2.98 MiB | (no base measurement) |
| query | 338.8 KiB | (no base measurement) |
| features | 2.91 MiB | (no base measurement) |
ℹ️ No base report, so new and removed imports are not listed.
Download the interactive layer graph for this PR.
Posted automatically by check-layers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The eval's simulated SES provider had no status clients, so an agent that read a sender's records through email/status got a 500. It now answers the status reads with the identity's tokens and MAIL FROM domain, binds the team for them, and seeded verified senders carry their MAIL FROM domain. Simulated zones have no authoritative nameservers, so the status check reads them through the simulated resolver. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he app - integrations-email-create takes the typed sender config, so the provider defaults to ses and a config with only email and name no longer returns 400 - the email flag checks send the same person and group inputs as the web app through flag_identity, so a flag released to a project id matches - the skill's manual handoff merges SPF into an existing record - the member eval case publishes its records, so the agent reaches verify and gets the 403 the case scores - the new eval modules carry no docstrings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dns.resolver.resolve delegates to Resolver.resolve, so one patch covers both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The email flag helper now lives in posthog/models/integration/email.py and builds its inputs with flag_identity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Create ignores setup_method, so the create tool no longer advertises it. The create tool test also checks the endpoint, and the skill keeps one sentence per line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Moved to PostHog#127296. |
Moved here from #116863, closed on 2026-10-25 so this fork stack is the only copy. It opens upstream again after review.
This revision
43333f81da9on 2026-10-31. Master gained the read-onlyemail/statusroute and itsintegrations-email-status-retrievetool (feat(workflows): add a read-only email domain status endpoint PostHog/posthog#120402), so this body no longer claims the status and verify tools.workflows-email-from-code.3c0a6bcd8fmoves master's agent setup flag onto it; feat(workflows): expose read-only email sending readiness over mcp #570 carries the same commit, so the two merge cleanly.92e394edff): its token tests and the guide section on scoped sender access.34d216911e: theemail domain verifiedevent now groups by the sender's organization, not the acting user's current one.4876fbd361), the skill's tool table passes oxfmt (89b56b97e4), andemail_verifysits once in the write scopes (fa6d94df9b).7e7a885a04:integrations-email-createtakes a typed config whose provider defaults toses. Before, the skill's email-and-name call returned 400.7e7a885a04: the flag checks send the web app's person and group inputs, so a release condition on the project'sidmatches.7e7a885a04: the skill merges SPF on the manual path too, the member eval case reaches verify, and the new eval modules carry no docstrings.1ce3487b0a: the eval DNS simulation patches one resolver entry point.641380bd8c: the create tool no longer offerssetup_method, which create ignores.Problem
PATCH emailand both Domain Connect actions, because none of them is in the viewset's scope lists.PATCH emailand apply-url declare no request schema, so generated tools would get untyped or empty inputs.This recreates the fork drafts Silthus#343 and Silthus#352 on current master. Their earlier upstream drafts, PostHog#109703 and PostHog#113059, are closed.
Impact
Pays into Grow Workflows through organizations that verify an email sending domain. Measured by
email domain verifiedwithmethod: agent, which fires on a sender's first verification. Expected move: small, up. Run cost: n/a.Warning
🟡 Merge risk: medium · two-way door (merge-risk rubric)
PATCH emailand both Domain Connect routes now goes through new request serializers, with or without the flag. A payload the web app sends that they reject would break sender edits or Domain Connect links.workflows-email-from-code. Copy that flag's release conditions to the new one before the deploy, or anyone it targets loses them.PATCH email, and the address check runs, only whileworkflows-email-from-codeis on. Create and verify keep master's scoped token access, flag or not. The web app's payloads match the serializers, and HTTP tests cover each route for session, API key and OAuth callers.Changes
Agents can take a domain from "add a sender" to "verified" over MCP, behind the default-off
workflows-email-from-codeflag. The backend checks the same flag, so turning it on enables the tools and the API access together.integrations-email-createsesintegrations-email-status-retrieveintegrations-domain-connect-check-retrieveintegrations-domain-connect-apply-url-createintegrations-email-verify-createintegrations-email-partial-updatePATCH emailonly while the flag is on for the caller. The check reads (integration:read); apply-url and the update write (integration:write), because apply-url calls SES. Create and verify keep master's scoped access.flag_identity), so a release condition on the project'sidor the user's email matches. Before, the project'sidproperty carried its UUID.redirect_urimust point back to PostHog; session requests keep master's handling.PATCH emailand apply-url declare request and response schemas, as the check already did. URLs and success responses do not change.email/verifyandPATCH emailon a non-email integration return 400 instead of 500.apply-urlreturns 404 for an unknown or non-emailintegration_id, and for an unknownproxy_record_id. Before, these returned 500 or a "try again later" 400.PATCH emailwith a different address returns 400. The check ignores case.email domain verifiedgroups by the sender's organization on both the verify and the Domain Connect paths. Before, a verification in another organization's project landed on the acting user's current organization.integrations-createtool stays disabled: it takes an untypedconfigfor 30+ kinds, including credentials.integrations-email-createreuses the same route withkind: emailinjected and a typed config.setting-up-an-email-domainskill teaches the flow, including SPF merging and keeping an existing DMARC record.eval_email_domain_setup, runs an agent with the skill against the real API over MCP onSandboxedEval, with SES, DNS and Domain Connect simulated per case.param_overrides.<field>.requirednow also works withinput_schema. Before, codegen ignored it.posthog/api/integration_domain_serializers.pywithhelp_text; the OpenAPI types, MCP schemas, tool definitions and snapshots are regenerated.Note
Turn the flag on only after this PR has deployed to Django. The MCP server deploys separately, and until Django has the change every new tool call returns 403.
Start with
EmailDomainAgentSetupPermissionand the three actions inposthog/api/integration.py. No web app screen changes.How did you test this code?
Test rationale:
TestEmailIntegrationScopedAccess(API key, OAuth and session, flag off/on/unresolved): fails if a token reaches the update with the flag off, or a session loses access. It also covers read-only scope, member role, a foreign integration, a project-restricted key and the read-only MCP policy.test_email_domain_actions_with_scoped_api_key(12 cases in the existing API key class): fails if an action moves between scope lists, if a response body changes shape, or ifapply-urlstops returning 404/403 for unknown, non-email or proxy requests.test_email_update_from_the_app_keeps_the_sender_address: fails if a sender stored with capitals cannot be edited, or if the address check runs with the flag off.email domain verifiedtests intest_integration.pyandtest_email_domain_status_api.py: fail if a verification in a second organization's project groups by the acting user's current organization.test_integration_domain_serializers.py(SimpleTestCase): per-context required fields on apply-url, a malformedproxy_record_id, andmaildevoutsideDEBUG.products/workflows/evals/test/: the simulation runs the real SES provider and Domain Connect code. New: a fresh sender reads its pending records throughemail/status, and a seeded verified sender reads as verified. Red first withAttributeError: ... ses_status_client. The scorers reject split SPF records and case-changed TXT values.context: proxy; the create tool fills inprovider: sesand posts to the integrations route; the codegenrequiredoverride works withinput_schema; the sender tools appear only with the flag on.test_flag_released_to_a_project_id_reaches_the_sender_update: a flag released only to the project's numeric id lets a scoped token update the sender. Red before7e7a885a04with a 403.test_a_member_reaches_verify_and_is_refused: the member eval case reaches verified DNS and gets the 403 it scores. Red before7e7a885a04: status stayedpending.Lane gate on the restacked head: the posthog/api integration, Domain Connect, email model, workflows email-domain and eval tests (701 passed), the MCP unit tests (183 files, 5,362 passed), the MCP and frontend typecheck, and mypy on every changed Python file. After the panel fixes on
641380bd8c: the MCP unit tests (184 files, 5,363 passed) and MCP typecheck; the integration API, Domain Connect, integration model,products/workflows/backendand eval tests (3,469 passed, 1 failed); mypy and ruff on the changed Python. The one failure,test_ses_provider.py::test_delete_identity_removes_tenant_associations_first, is a master test outside this diff. It fails the same way on the pre-fix head in this ordering and passes alone.hogli build:openapiandhogli build:schema-mcpregenerated cleanly.CI on the fork: the depot jobs never get a runner, so the change-detection jobs never run and
Semgrep Checks Pass,MCP Tests PassandPython code quality checksfail. The lane gate stands in until the PR opens upstream.Frontend formattingfailed once on the skill's table, fixed in89b56b97e4.Proofs per qa-swarm
PROOF.md:👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Release status
Docs update
Updated the OAuth development guide with the sender and Domain Connect access that scoped credentials get while the flag is on.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (
claude-opus-5-5)43333f81da9: 18 conflicting files, 9 of them generated and regenerated rather than taken from one side. The restack keeps master's eval flag overrides and test assertions next to this PR's./improving-drf-endpoints,/implementing-mcp-tools,/writing-tests,/writing-pr-descriptions,pr-description,modernize-pr,merge-risk,tdd.integrations-email-partial-updateneeds the sender's currentname, and no read tool returns it. Makingnameoptional changes the API contract, so it is left for a separate PR.products/workflows/backend/tests/fakes; add an MCP test against the real API transport; find the test that leaks state intotest_delete_identity_removes_tenant_associations_first.integrations-email-create. Whichever lands second keeps one definition.example.comand invented domains.Decisions
workflows-email-from-code; master's agent setup flag moves onto itemail domain verifiedgroup by?redirect_uricheck apply?flag_identity, instead of a hand-built project groupInvolvement: no grilling rounds, no prototypes. GPT-6.1 Sol (high) reviewed the restack in round 1 (one finding, fixed) and in four final reads (one finding, fixed). On 2026-11-01 a two-family panel reviewed the whole diff: nine GPT-6.1 Sol (high) lenses and a Claude Opus 5.5 (high) fresh-eyes lane. Round 2 raised 12 distinct findings: 6 fixed in code, 1 fixed in this body, 3 rejected, 2 follow-ups. Round 3 checked the fixes: 4 findings, all fixed. Final reads follow. Proof: command output; live run owed.
🤖 Generated with Claude Code