From f21eb2531ff7f82a72b54c6d4a52383b1969816d Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:05:15 -0700 Subject: [PATCH 1/7] feat(favicon): environment-distinct favicon (dev/staging), same wordmark Recolored the existing "sim" wordmark favicon (background only, mark pixel-identical to prod) for dev (orange) and staging (yellow), so a dev/staging browser tab is never mistaken for prod. Production is untouched. Deployment tier is read via the existing OTEL_DEPLOYMENT_ENVIRONMENT / APPCONFIG_ENVIRONMENT / NODE_ENV fallback chain already used for OTel's deployment.environment attribute (this app deploys to AWS/ECS, not Vercel, and every deployed tier already sets OTEL_DEPLOYMENT_ENVIRONMENT in Secrets Manager) - no new infra env var needed. Wired into both the /favicon.ico rewrite (next.config.ts) and the tags from generateBrandedMetadata() (ee/whitelabeling/metadata.ts); a whitelabeled deployment's own brand.faviconUrl always wins regardless of tier. --- apps/sim/ee/whitelabeling/metadata.ts | 60 ++++++++++++++++-- apps/sim/lib/core/config/env-flags.ts | 35 ++++++++++ apps/sim/next.config.ts | 17 ++++- apps/sim/proxy.ts | 2 +- .../favicon-dev/android-chrome-192x192.png | Bin 0 -> 5967 bytes .../favicon-dev/android-chrome-512x512.png | Bin 0 -> 11762 bytes .../public/favicon-dev/apple-touch-icon.png | Bin 0 -> 5542 bytes apps/sim/public/favicon-dev/favicon-16x16.png | Bin 0 -> 391 bytes apps/sim/public/favicon-dev/favicon-32x32.png | Bin 0 -> 795 bytes apps/sim/public/favicon-dev/favicon.ico | Bin 0 -> 817 bytes .../android-chrome-192x192.png | Bin 0 -> 5997 bytes .../android-chrome-512x512.png | Bin 0 -> 11660 bytes .../favicon-staging/apple-touch-icon.png | Bin 0 -> 5576 bytes .../public/favicon-staging/favicon-16x16.png | Bin 0 -> 390 bytes .../public/favicon-staging/favicon-32x32.png | Bin 0 -> 792 bytes apps/sim/public/favicon-staging/favicon.ico | Bin 0 -> 814 bytes apps/sim/public/icon-dev.svg | 1 + apps/sim/public/icon-staging.svg | 1 + 18 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 apps/sim/public/favicon-dev/android-chrome-192x192.png create mode 100644 apps/sim/public/favicon-dev/android-chrome-512x512.png create mode 100644 apps/sim/public/favicon-dev/apple-touch-icon.png create mode 100644 apps/sim/public/favicon-dev/favicon-16x16.png create mode 100644 apps/sim/public/favicon-dev/favicon-32x32.png create mode 100644 apps/sim/public/favicon-dev/favicon.ico create mode 100644 apps/sim/public/favicon-staging/android-chrome-192x192.png create mode 100644 apps/sim/public/favicon-staging/android-chrome-512x512.png create mode 100644 apps/sim/public/favicon-staging/apple-touch-icon.png create mode 100644 apps/sim/public/favicon-staging/favicon-16x16.png create mode 100644 apps/sim/public/favicon-staging/favicon-32x32.png create mode 100644 apps/sim/public/favicon-staging/favicon.ico create mode 100644 apps/sim/public/icon-dev.svg create mode 100644 apps/sim/public/icon-staging.svg diff --git a/apps/sim/ee/whitelabeling/metadata.ts b/apps/sim/ee/whitelabeling/metadata.ts index 72ce29b3242..f89a3fb2731 100644 --- a/apps/sim/ee/whitelabeling/metadata.ts +++ b/apps/sim/ee/whitelabeling/metadata.ts @@ -1,12 +1,58 @@ import type { Metadata } from 'next' +import { deploymentEnv } from '@/lib/core/config/env-flags' import { getBaseUrl, SITE_URL } from '@/lib/core/utils/urls' import { getBrandConfig } from '@/ee/whitelabeling/branding' +interface FaviconSet { + svg: string + favicon16: string + favicon32: string + android192: string + android512: string + apple: string +} + +/** + * Same "sim" wordmark per {@link deploymentEnv}, background color only — + * so a dev/staging tab is never mistaken for prod at a glance. Ignored + * entirely when `brand.faviconUrl` is set (a whitelabeled deployment's own + * favicon always wins, regardless of which tier it's running on). Kept in + * sync with `FAVICON_ICO_DESTINATIONS` in `next.config.ts`, which handles + * the legacy `/favicon.ico` path the same way. + */ +const ICON_SETS: Record = { + development: { + svg: '/icon-dev.svg', + favicon16: '/favicon-dev/favicon-16x16.png', + favicon32: '/favicon-dev/favicon-32x32.png', + android192: '/favicon-dev/android-chrome-192x192.png', + android512: '/favicon-dev/android-chrome-512x512.png', + apple: '/favicon-dev/apple-touch-icon.png', + }, + staging: { + svg: '/icon-staging.svg', + favicon16: '/favicon-staging/favicon-16x16.png', + favicon32: '/favicon-staging/favicon-32x32.png', + android192: '/favicon-staging/android-chrome-192x192.png', + android512: '/favicon-staging/android-chrome-512x512.png', + apple: '/favicon-staging/apple-touch-icon.png', + }, + production: { + svg: '/icon.svg', + favicon16: '/favicon/favicon-16x16.png', + favicon32: '/favicon/favicon-32x32.png', + android192: '/favicon/android-chrome-192x192.png', + android512: '/favicon/android-chrome-512x512.png', + apple: '/favicon/apple-touch-icon.png', + }, +} + /** * Generate dynamic metadata based on brand configuration */ export function generateBrandedMetadata(override: Partial = {}): Metadata { const brand = getBrandConfig() + const icons = ICON_SETS[deploymentEnv] const defaultTitle = brand.name const summaryFull = `Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM to create agents that automate real work — visually, conversationally, or with code. Trusted by over 100,000 builders — from startups to Fortune 500 companies. SOC2 compliant.` @@ -90,23 +136,23 @@ export function generateBrandedMetadata(override: Partial = {}): Metad manifest: '/manifest.webmanifest', icons: { icon: [ - ...(brand.faviconUrl ? [] : [{ url: '/icon.svg', type: 'image/svg+xml', sizes: 'any' }]), - { url: '/favicon/favicon-16x16.png', sizes: '16x16', type: 'image/png' }, - { url: '/favicon/favicon-32x32.png', sizes: '32x32', type: 'image/png' }, + ...(brand.faviconUrl ? [] : [{ url: icons.svg, type: 'image/svg+xml', sizes: 'any' }]), + { url: icons.favicon16, sizes: '16x16', type: 'image/png' }, + { url: icons.favicon32, sizes: '32x32', type: 'image/png' }, { - url: '/favicon/android-chrome-192x192.png', + url: icons.android192, sizes: '192x192', type: 'image/png', }, { - url: '/favicon/android-chrome-512x512.png', + url: icons.android512, sizes: '512x512', type: 'image/png', }, ...(brand.faviconUrl ? [{ url: brand.faviconUrl, sizes: 'any', type: 'image/png' }] : []), ], - apple: '/favicon/apple-touch-icon.png', - shortcut: brand.faviconUrl || '/icon.svg', + apple: icons.apple, + shortcut: brand.faviconUrl || icons.svg, }, appleWebApp: { capable: true, diff --git a/apps/sim/lib/core/config/env-flags.ts b/apps/sim/lib/core/config/env-flags.ts index 92b7b26219c..531a447810a 100644 --- a/apps/sim/lib/core/config/env-flags.ts +++ b/apps/sim/lib/core/config/env-flags.ts @@ -18,6 +18,41 @@ export const isDev = env.NODE_ENV === 'development' */ export const isTest = env.NODE_ENV === 'test' +/** + * Raw deployment-tier signal ('dev' | 'staging' | 'prod' | ...), read the same + * way `instrumentation-node.ts` and `lib/monitoring/metrics.ts` resolve it for + * OTel's `deployment.environment` attribute: every deployed Sim tier sets + * `OTEL_DEPLOYMENT_ENVIRONMENT` directly (dev/staging/prod, matching Go's + * value space); failing that, `APPCONFIG_ENVIRONMENT` (dev/staging/production + * — mapped production -> prod); local dev has neither and falls back to + * `NODE_ENV`. This app has no AWS_PROFILE/Vercel-style env var of its own — + * `OTEL_DEPLOYMENT_ENVIRONMENT` is the existing per-tier signal already set in + * AWS Secrets Manager for dev/staging/production, so this reuses it rather + * than inventing a second one. + */ +const rawDeploymentEnv = + process.env.OTEL_DEPLOYMENT_ENVIRONMENT || + process.env.DEPLOYMENT_ENVIRONMENT || + (process.env.APPCONFIG_ENVIRONMENT === 'production' + ? 'prod' + : process.env.APPCONFIG_ENVIRONMENT) || + env.NODE_ENV || + 'development' + +/** + * The deployment tier this build is running in, bucketed from + * {@link rawDeploymentEnv} to a fixed three-way set for UI-facing branches — + * currently just per-environment favicons, so it's obvious at a glance which + * tab is prod vs. a staging/local build. See `ee/whitelabeling/metadata.ts` + * and `next.config.ts`. + */ +export const deploymentEnv: 'development' | 'staging' | 'production' = + rawDeploymentEnv === 'staging' + ? 'staging' + : rawDeploymentEnv === 'prod' || rawDeploymentEnv === 'production' + ? 'production' + : 'development' + /** * Is this the hosted version of the application. * True for sim.ai and any subdomain of sim.ai (e.g. staging.sim.ai, dev.sim.ai). diff --git a/apps/sim/next.config.ts b/apps/sim/next.config.ts index c11bcd6cc2c..3641e236607 100644 --- a/apps/sim/next.config.ts +++ b/apps/sim/next.config.ts @@ -1,7 +1,7 @@ import path from 'node:path' import type { NextConfig } from 'next' import { env, isTruthy } from './lib/core/config/env' -import { isDev } from './lib/core/config/env-flags' +import { deploymentEnv, isDev } from './lib/core/config/env-flags' import { getChatEmbedCSPPolicy, getMainCSPPolicy, @@ -26,6 +26,19 @@ const minimalRegistryAlias: Record = useMinimalRegistry } : {} +/** + * Per-environment favicon for `/favicon.ico` requests (the legacy path browsers + * probe automatically) — same wordmark mark as production, different background + * color, so a dev/staging tab is never mistaken for prod at a glance. The + * `` tags Next renders from `generateBrandedMetadata()` + * (`ee/whitelabeling/metadata.ts`) use the same per-environment set. + */ +const FAVICON_ICO_DESTINATIONS: Record = { + development: '/icon-dev.svg', + staging: '/icon-staging.svg', + production: '/icon.svg', +} + const nextConfig: NextConfig = { devIndicators: false, poweredByHeader: false, @@ -438,7 +451,7 @@ const nextConfig: NextConfig = { return [ { source: '/favicon.ico', - destination: '/icon.svg', + destination: FAVICON_ICO_DESTINATIONS[deploymentEnv], }, { source: '/r/:shortCode', diff --git a/apps/sim/proxy.ts b/apps/sim/proxy.ts index 3c8247d2706..96e2f79c8aa 100644 --- a/apps/sim/proxy.ts +++ b/apps/sim/proxy.ts @@ -318,6 +318,6 @@ export const config = { '/invite/:path*', // Match invitation routes '/api/:path*', // Runtime CORS // Catch-all for other pages, excluding static assets and public directories - '/((?!api/|api$|_next/static|_next/image|ingest|favicon.ico|logo/|landing/|static/|footer/|social/|enterprise/|favicon/|twitter/|robots.txt|sitemap.xml).*)', + '/((?!api/|api$|_next/static|_next/image|ingest|favicon.ico|logo/|landing/|static/|footer/|social/|enterprise/|favicon/|favicon-dev/|favicon-staging/|twitter/|robots.txt|sitemap.xml).*)', ], } diff --git a/apps/sim/public/favicon-dev/android-chrome-192x192.png b/apps/sim/public/favicon-dev/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..5fe8149bacea40429d5db87794b325d6e064fe77 GIT binary patch literal 5967 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 Tj|BWzl;6m&XB=iFc=|-h!%|AA_&pD!616{ z65Z&%*U{&>@9+Bl2hWesXRW(t&RTQloO|~<`?X*DwReb)mKrS;D-{R?qJ8yJRTl&z z1%{*`%KyGltSSW{kVwrd)o1!1$y?J%Z}!m-vwNQ6Wp_gH&u)>wjN%c9vVWLsZXn(1 zvRP&&S2$SnZqZ1T`FR|FXRD1|iBF+(s71T8WsT~dfIFk5fqvZt9_cF& z2$atMzrp{E@c-;dCq7V(a*!tVq#A7iOuaR$ioNv_(tK zBtzpxeZai~!H}#}RHTME^+cAicndDdc;& zykSBC8RK)1j&tx};BPLLSEgpiR}Y>+Hp5nk%TX$oF}`q)bWu{jujk9hA=70we%sDF z&|6Y1juf}RDBre*EmD0okdAS!4PtaBQr53=3z$NTdV2#69SxEV)Q7H!-W z*O!nRYGYGs`a;*Y?krG}Ey)e*z2379pD5(qSf1x)x?7+&=1@gzeYG zh)1s|KAI&X^`pvbDfTh7XVNAE`Q8Km8aX%lkJzk{5qtWQ#P1gHyFFc!uRLg%RL#D` zZ{U_WE25F&ztx4A9Bw2i-W+%Sx%o9Qg@F`w;s;9i_pA%-DH$-F(ErT>x zj~__$OQQrWcmA%m7)`EnaI@fdjANNWhF^+(80>LUMw5F zp9mhQ404SsNr|f!xF?CMO#8Ma5%^6zW#lxP8Y323LZGYsj&O0f z)!dn3iN|ce7JD#w`JF*!2TqCmV0U@`R+1q7Ij=Uik*DqXKNA~umcGfox@h62c3qw0 zTKFitjVg*h20d~&2C2hex$UH0dL6bjtR_8jH6ku9rj|S~1<8bQsRV_1!EPqN9}Bn< z&sBC?FuON;=8WEx)G@q&wm_4FKre{qo;>8p=&kLG)V;2!z_gqJn8o^)={v3Mz zc-jmpuCD!d?Qo=c9LhD-f6Hu$(PWZ+`|C*mE7PW^;F;mxgiV}>udGduFrS5tj2e?K z`cztP)E~?FL>2OwEaeTtK*iR|V)vx2KXKW~re#>@;!}IcJT?_Af?{N}x z`9lLy7ZZcYbW`oFDzdHfcHGc?VRY6W<wjB9 z)eU@9IlLcURxawXw!YjoS}|hi+tH)MGs7XNlDhp;+ghY6Dg`0K?&~2e8Cwxnvni1> zUwATH`BKfYw|#nnWn)xj54xE&EgSWUkv+ri(>&q0u1|DJK|T225y@rwamS>gL_Odx z-ikNtQBug}#?2y%g<5Nugn6w7*C{itFRypH1jDT;S>~&Q`UC5a(B*X>eAHXoMcN

vD1rUktsq)jI!4RhES^L+ip$;M!aA=vP)N-dcLSnwAA= z+o@N3h@taap7kDElZ3P)Q~&v~BHY>RxuJ9e$_jxB992bG3SUM~4>fRp1x#{)Jiq*# z5-~z?2$+`WV3vac=iNx(NA4iB#)e)uf?6ZN{07 z_fLpx?KdxNM-SVz98f!X%SzX*+k8Jt5qfgkiLiUArJM6(^M6xwv2Ksc>v-W)Tn$@F z^P7cO?R+@+cjyDIjJk2YGPubrdh9uhrQ7F9=XvY0D^OOz4Bn_1b@ zkCW@r5=WI+*$q!~Q)=}N(%lKKsZ*9Z`sCeL|560m9BBP&yLkb9JzD-HW5(x^XQv~X zw#HAPv-;QVWl{5UHD>bRoP8z~x`6=#FnQS0^t0a$mvn;8GFjfnlc!U+Gk0n%h_`Pi zL~<_^rEmhO9rQpn-@*D22}mu@$3Hu2a~_Jr8ytx%sqA6Q$xg9_x>P;&LbETo_-b?T zu3fkdLbtw!(6BN{kjGI5?KSfW?!YDO_U1s2$o!e6#72tvsWym{<+lS_`2DYG$^`Qm zC!)>*+LSEh0`+l*_|MV8Q>}OH?E8*#&`YM|1}~4rOw*g)%UdpH>+OA-^$V4s+S>*h zEJO(!f+~y=&tD7%Mogn;`?%P(82@^~o?`Qe)yx^?OYcgS8v6)6s^0>uygqc$^RE2~ z-sbdn@V;U#)^T8Yg}WU2gnFS{QJg6}{pSYD{Fy=-+WY*fNfqBL#Q1e3*HFRrk(tFx zZZ>@o{pe<*7cnK^e7?pW-uuIVnrq?t19(>iTxJ(aR#xFXKwKro-t95s!r81Q6F0Mvv^O6fRJikj9lofw55`R^R3pRX{(f8XKE#pDOeub-Mwu3j#AsdHW_wkC z9)8)^yZa{pOCUBn&p6HVq8}}~SdV_C#7yx$P+Reld`ekfy@=%8nSwaibd_BeqWaT_nJ1fncvGz?nt!&;V^icg;nd0*&evpsJFe6{bWhW`x$#K zux-+*#K!6WW}Izr(2dR|6BmrW(lkZQ>&Yca21=od@~z8j)-!ygPD*r+@Hg+cn)jBaBZHmD{k( zyR{K8&MwA}3XvCaDbbTTrAy#1^iqdO$L%|Jwd!7!c$(lUd@hdX7XM6~6OU`CxD| z4F+v(t1G+qMdh0P1D>G%7lR|rsq8)jU}A50NITykHF5`fCb8^zy4FtjSh0thJpG-x z%=wJFc3fFbWUInv(mAWI=Le!ydzI>6a4dfw^(vRikXJL?nW)h%p)wL~6?ut7+{$}h zJ*72@)1Dl@Y{c=O8uc^t4=Pjg@zu`gi(Rm%wct4r87}I*t|nQC=&GMh7nG~!0PUEZ zzC;|v&S{9t4gGC+UUd98lO_@BNtnXuYbEi0mo zoYr~f<$iWk^$MSbI$70zFBfNp0c*8^lcgs(($HG{^eCr&XaufC?qk#5;@T^?!i*pA z-O*eM4Pg9A7gcjm&2hRd`1s-0OKz2hrDr6}S9iRnqt! zt7JI5`IS6T<%Mv1lJcTMLV5C9vYgq5Ql1mPW0+OJ;JQg{{ITe-P(HpVqdN&TnHkcQEHbvdGL0PL17>zQ?dHW%V9y&24 z9wQ9kuP4l}&`!_z9FuXf-sbMON3}X164H%P$(?<7g%Muk9HY_JV0Xh>r6jT_xtM>80S&a^LfW z5P->6u&<5cbnPb$tHN@qdLLhPhZ-KFT%Gj;3GC%UtY*nRQ|L{WvklBh!$-Tzo`Ag~ zM>ce6wZA`=*^k%zlw|XD_F*v+!<&}U>3J?cscXtaU1#w;TB<=5@~^Ix z+tw5NobPLB89b%iHgUb-Ru*g?jV(M{4t@I$S6Gl-PmCIo3MTITQ*S^X4_cMHPmtcC zyPb&f$V%Y8S(YVtf3EbOh_u--F+;MzYWp(cunixS)_~h-hM71Btkl)5bUpg){>bst zntyI+Blio)BTo1!0CZI#Ms`nkWd5K!szG0U%o_n+*ts6m9maoCc)aj}eL%+axXphw zb>^Iqgf)%u%9u%#CP-e*A1Tt{Q#Qmro1!$i7ffwLPJ_kcVh-;9?Xsg`h052jbmb7p z-R4Fq`60FqQ{at0m_P`~Lpo7FV@VipvyScWT`TPUJIYLuQq`QE6ierB8PW^ApqX7Q zt(319KMNft7#!BDE*&+&dQIKmzw-SU zrm2$9%+ zB)g(kGWhN6*P2q-!vuT9%di5ATPSMHQ0C->eat=R7pm}g1N0Z$z=twlttqzY zwhGi>+Wqlu^EWiROtjvWfLf>-NTEo@Cz! zG;P9J8ByK+>bmBfC=@H5N`TigDuePevA1FFFEqNGxy+7sW08v*zNy<9BVX!7z#iUR zH3}v6j*Ye9Fxeu$<*lHhH;WFZ>xEci4bDEoT{^h?xAxj2SEOKu%Oc119M6`3_Xg?I zk0Etv`eVoVqp9-GVS06``^@YtlFTd7jcA>wC;+YurqnTtj|@NBqMalh)x`+OSNDvQ z#g4_awtsEMjKVh^J$k;6i3Hr}E7Oln?eGi=nUm)R;jg(x#5sTNx86TiZObF z{&)B6U!agYaR-seXOnSTxpx2OakfsZ$)#Kla-<&nd%Kd%YKuQ2rfdnl0h9mzTh<~f z;xMYB07=WYwDWNOxRKtRztg12j2^VJPKvF{X>`>LUD?RlXepIkvsz>^D*5nS9?6BW9b7>*dlA=Jt`D2(8;L zVF_Y)KccEDu5#E{;qZ?+$1hFgp({&ASXe&wF}P zF~vw@4yds7w~gi8y2Z_AACb;N4DZjL#y_zAQX3R~J}=WCO@$M9y8juoyJ2s=HNG6_ zX>F5IMe)?^etPI>TJSo*S=s#&R;lFDw<2y2OTUq)hyzpD4Cf!n=J*%d-8MdF6NVW! zJFMY<AElw==C#3vqI71u3eVkNaErJ#f@0tdz@35t8hO(YHi9HQ_ zX5s16e|(lp%Q8>gN~rnZmz!_@#ts`kI@&#l?mWXd>2>fQutthhAZjgqMHIH;fB@#w z_QF)R?f;u(;*4Hcm;{n?Q2GQ#ubz~CZ-Drn;4@G+ANov- z#&lsOvcqk|rmhr(EmwVxnq0zT)Yat+?eb~@Q_eR6daRPCo(^)90$ZQ!2a2&msFe#W zUM?G~Ntp9k_^hU8aBU~i=!I>-D=%y66vvFSLMS7C)Qa}sdcsk( zGE^CJC*=vega>40JU}m7QIMZxn05U=buU!Wdl%5Ok-JJ3wEVQuP~)r|iSUoc5GAiV z-TBfick?jFs9;E<7jk&{avVYp z$DfyoP;7I&vi4><3X^g9=>X{6g;hnY@jf{yug?a1 zKIp|OFV=H9eWn?ZYEWlouWgHbQ%9i_irxw}2=irR!gRfrCOY(W8@27jA~IkmV@?tK z?iw~#npU_5gv%?)EFh2ql5?)(fI-+ZbDcMXKAV*0M8=O3KMRUFyg7Xg6iNovjw$z=kn zb2yx)XOb##Ju)#rm%=Z?k`fL(t=nw~h8-1L>oU6wLbT$Vx#9{x;yfSuLRrLFIRp8p zABf^gc`GhEFYq2$ZB669a;t)S+K4ZZQqt&h}6UJuI1-*fYTe6iJ4a|cOSAUA8l91Q#Majwp8zp50Cci*`PEe@o8*@kh8Xjmg=6+ zs+Rro$4=WeERd?SUG9w(?*aH$btswIaQ|&VRtSkcGs&+nRmakzMRf0uW}6D46N=xc z=)LB|X)uaCm8NMy*MNP!^;SiE!gfsmP4#G6C_R>x?zo65RfQ5Bjf!Kwztl`*#f{MHb}5)xyH3_Y$21ceA?p;k*HYlyGSv>#@Y*fMgsdrK4~aZrr)xu z`q;&6;s~M8-WO0Mp=5g~weMshbs~~_V#rjn892ktBYLjacdnL_t?K0;gM?p@r^_k_ z`MOt~ON_YodcBwMS#g?g8aTXCRkZj|y@#y+I2-yAOuKjDv0Pe9QKV25cO4W;NAjx_ zh!f86W&knv>gp|IQ8O9C78YxevYNeb246qD`6nJw%v}j+8?Jr*4fWPCdSRrYG!26l zKe%m^@y19mo0M$3Xyc9Xgeh^o@!)pdT5Ci=r!saHA1V1+iWrTpSs}T-_M21oBmfbY zAbF_4=I6rTXEMwx)wlknZ$0lk+N~hOUm>ysESccrDty`P>JH^e6CU$4O~gKGk%tI; zy?YjRzA)qAb15BK$q z<#wJ1Ia%lo*aiCsog9nbUU6*)(k-DAM^HB}X>p{gMtuYK@C?1z(EfF`zkpk;Xt-~v zE|=_eAM8yz#Qjs4qx+HCoMA8 zEwYeMSV?d%$OJa0?;*YiI z*wipXy?2UKq9~vt^9< z)uvEZ!*<;oU1?*jEx*&{mXXfQ$CboRM6GM&v0mibL&j< z#5nyh!m3Y>TSCOR7=AbY$c~Ie|2B!yg-P>rEZYPeYukEF-F$o=GVcLgC%sA!J7VKWArA z_l|UaD@wYaPDSbGqF9v+vrsEfHW1{{R8&Yfa?1qilaT0W`81wv{>GYy#0q-xRW9EKFlG zM(OthkkQ#k@9sr;xXbR@|0KKm3H2I3bqUk6~U)!=$vF?(kws8P9HpB@2NcvEwc zR=aG2Qqy#X^(LF-!1SFXZa6WsU&7RW32aD{j-_l&o|cb4StM(A`y{i|lI6-be9_Y? zG$IjL!Pvd02F2A=&L@7X&p^w<4y!`z0rN?A13&VM#J%ASQXz*;eeb6WXVL zUp8FP@{0&>F8m|cXx>~%$f0x^C!GhaQBzb-g<6t|yfUS*2QYO|y0f(nL?$}p8qFTv zWE&cXe31lg&i&I~MZ-rOzQR?IDksxbtdjXw^-ne@;SuwV{}QMfNn?>Wd26 zdG7?BbeNGh`MAI#bXRA8pw$--U|kQ0J}IN0~27nFxf;`53S_`i>q99^n>&#?jHf|&JSw(Z*h1hM|#%6UHUC!60 z5#Ms)EMI59-&tRoW{du@Vn2y9(glRE%g%|BCr}Edt^c_6%HM220Rn(QaAojy$hO&A z7jdVd_ZL7hu<%PwrA%FhWND?qupyTNZBp1X1@m>a!iShDs}c8G*ZAHP^OYT6srmxA zdamz2>hO`rVtg>Atn7kTC`$MIB*ZZ#HIY1Biovfm9((dzPc|+7Zin1p+@wGjjcuY- zRM`%@7SL(Jn8+mcT(AEZ^(r?6>~euy>ZlVL!bDf5c;H28)&B+78jwIvs(<%R>;rXZ zLc#JnxcC>npNr%A7c)2Aa~n>!qYa~4RWUPW!OQWe3Cmv5g8PU?r;Nb@ii{iF5_*(n zPb?5r;hRNtzP@_QWep^uG?{+hPOUc_0mSYYvy#8-uK(i%;ey=z;bBXxEgA$rR=tM) ziivrnM+_E6VcMz*)WTBajTBgVsAB!faHVaf*U-7Xzeq)TA$sjFwXD{2pW5g%r5_jo zTtcrI7W+6xY+;}{(OjMIIIz!g-3zd=J)GL_>pc+8c>M0!+-cWaDRKlgQNHo};BZAB zd>!ZNre0BXO(}~W1m>7w#2sJYZ=3v~J~IK*Ww-3B3USOkcX<^0{bOE`q8v`(;$V~j zG+ijdx?WE+7XHi^F_ijTh}v=~ya0uAlI%iF$Lf~r@Y;oN1he0}r&Z*_0teyV>d@vs z=uA~jX5mBL8t_hX04lSO#5J%Ea&&}bDwy11V=ot{+37&6cp zr?uk=Loa|8#hpi;p1`_v94%*e3yGRtY>K6YN8hvxPeFgVK?id{Cx^J~22errMYb<0 z@OFNCK!!ahhZ`8_nuIe^uL8Xv=u_-S8FuW53~2f~SlQej8=o!#%2D7MX~f2-miIq^ z&W}G@kQi{+p-n-OVW94+FpdG>5|U;FmYaSO z<6+K&cm(M%3SUdTeZoX$eBts{&PQ`-o%GDPq#sC309g>e{Y~n+@el)u0X`9e_%d~9?r#~s12UWyH0#ua~KdP>2KNyt- zu14Qv@lsLR;TIKjvNyFvs7>d!y%%ou$XUs-bfp|N%y#(m(ur}wDc>X#z~*0yGt@NexmUOM;@bT$X`ApyPM*U3 z5ay>YBnj(+so^iXhL(-Old5Vi#aiJjjtm;=uU9%et6(9*SB@SiSmgpvvf!aG zJL=H1$O#{qq;k!{|_X9T44YH literal 0 HcmV?d00001 diff --git a/apps/sim/public/favicon-dev/apple-touch-icon.png b/apps/sim/public/favicon-dev/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f702551aedf0fc304b43e8a1259c6e6c5ac97df9 GIT binary patch literal 5542 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 literal 0 HcmV?d00001 diff --git a/apps/sim/public/favicon-dev/favicon-32x32.png b/apps/sim/public/favicon-dev/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..c13edee09cacfb947adeebe391e7169793a42042 GIT binary patch literal 795 zcmV+$1LXXPP)`Z~{=o8pT>}v9F#tL4CV&7Wkt9kdj<6U@rq)wWMd>lNH-^x8=WFhup(cWjUhbLyQMNv zY}J(&w2g&Fmux`H$bTDvBT_=O28+AfgZD-ko=hwm9Pgi~sV_7grBWJt4U|cRk{m@o z!`)kzP#~DGJ#sdQ2ml$*MC{X5g~J_<{K zfFuHo^?r@i^^Q->uO|tTl1eNt5FH(CYx}3Bzmp?yYusTwB#O&x&Hhgj`@+DK#j(iX zkJ^I-U~#txO^!mBl1jWFRhKs1u~}-sEO#;AS}cj&ah0s$^mfyNdm^T%#swjL|1r4Zj=0y26ZZOGhQnF9fwAS zL}@0taY%b2ZaO;T?xa4O(n3&rF+J0vcWRUckj7+w%k*@c|5nZMf4^}4+46v#mIpvC Z`w40_KnO-`6wCks002ovPDHLkV1f!iWB>pF literal 0 HcmV?d00001 diff --git a/apps/sim/public/favicon-dev/favicon.ico b/apps/sim/public/favicon-dev/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5ce2a43837dc355d5efe8a78c3a83056a203c72e GIT binary patch literal 817 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 Mr~av0#xm@G037Jxb^rhX literal 0 HcmV?d00001 diff --git a/apps/sim/public/favicon-staging/favicon-16x16.png b/apps/sim/public/favicon-staging/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa3c7dd8c94701619c90dafdf252868cc373d53 GIT binary patch literal 390 zcmV;10eSw3P)LEKmsNPsxDpGSQw~K2PjQ! zCx@J-(4h>K5Kpqtw%+r-I~%&6(lQWBvFUFFRYlCd3gkS`fk`E(G;2cy0y!~2Vs`T^ zGN}kkky^*qt$7)8m?CUJB?#A`B1f14x}R1|en5|d@~&swJKpe(laMBsUWZj@*SqhP z-6PrAlO|_@Is-F_0OvO*4iP6PG+#g1(TF!vadv5rGkJQUxnz7>5+IxNN!MR(p*OIT zoB~OQ2Qu52?JbdIawUc-nlhTAh371dCya_zL}7ru;Lp5n#s>$!tNW)07vPLNJy+YC zLK~VC9ESj?(40hgA9E{d6pdgCUy(~)H?gd{EZ`QNM`gL_;dJexWHQzzWF}kltX=eQ kQ)6y!#@xwl`!ApG3!(dn=qxvwHvj+t07*qoM6N<$f~1R~c>n+a literal 0 HcmV?d00001 diff --git a/apps/sim/public/favicon-staging/favicon-32x32.png b/apps/sim/public/favicon-staging/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..386682a32987abbcc21723c663209c02df2dc200 GIT binary patch literal 792 zcmV+z1LypSP)gqa z)S?eCp(1plC}l~7Nq)Vaqt48|C+_pnd)hNA6k5E)UCi9eoZmVB^S=zbukv9%gRN_J z$N>HzGJrJ$5Un#nm}?3k0;xdCMBxl!Y$DkL5h#`HNs(TE0U!d#z|KND2Mq(bjXiyG zb4j%AiDzb^FZHPv)JHOou`Ioa(#yCUKm?`$UqVNx*L27I^p%)^f_$th7rVFf*fd!} zch)~BqcO6>C<6FyR1JSnLV#hUVHnG6=P)rtCu^OFY0AsR+RO8e4S}LUK02lX7M!V{ z%g@0#gR*}}hJtwQLg4;$zxjc;;8AI@akVZOv_MHfT%iM{zzAb|w>R`ry={whwMQxs zn|Hgt1s6Jd8t@Xh*Q>tny^o@<0qs+Btc1n^;7 z0h{?w4Oixm95gT0*cia!A(@?p!USg?PL!HQj|*_&T&3vh_3KXC1zXv!o$OGH(Lbz! z=^QK0fHQDoRC2()Q6GHt(yyqQ-B%ua(d&n7^rcpph_nc^q#W{m2nA64Ekd8MCXBq7CHwi)+u_%(k>b6)`r@3F#F_pY(%E#$3^)TnMpYHoz=$e4?+6pJ!g#$tpv^Ay zbrYucVxlwzTO_MCO|8bHPJ#^U`11kcq%bFQhr4+hsqzD#t$^U-_SGbKbIsfy&47#uKVLgMbYj(&0{va}dH3JZ>GeDSY3LpZhK*~hn3}I{{*#Z$L zmF!88UVi}~0>;43LOTZy1GtSneR6Y2wC#y!W}z?jsTI^mGLEq_-<4Ue^5ezVWeRg%WLN_F+(S7 zor!76%f;Hu^NkIGqC!48rUDk6sh`Ww!8e1le@KRccS;ukc z*{$%+`e5s0zv-T9gixxLI{*amVOs&4`A!X2=8qgSFV)x>z~Ld8orS^#XC6+Jnn#Zd zaN%5~=<4az&tbpkpE6#v3aAQ<*z`Ri(eDu<VdPx9lj7M^eUfT_eL2$Ebjb`j z13yMp71qFrDm(886SBg1y*{ALF7$O1ruJf@Gz42Dt2Rxo(yxKb{>el-1rzxBi*jAs zv4sH#XBNgM)y7;l6(wOp&ISa6`33kktv2N`9+zu;k_-;H*+}ZQfJMgQ{R9Nh)k1Tw zslE>e*GIlgbim`Ai=vrE@@Peg5=_*~bra7lKEMT6XLP;9=HdXPn{-a<(JFwSnABjH sW;69Qtw;Z-AI?8V2C!;m0I*v80K$At$jftui~s-t07*qoM6N<$f*ad;w*UYD literal 0 HcmV?d00001 diff --git a/apps/sim/public/icon-dev.svg b/apps/sim/public/icon-dev.svg new file mode 100644 index 00000000000..8805cc3f5ff --- /dev/null +++ b/apps/sim/public/icon-dev.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/sim/public/icon-staging.svg b/apps/sim/public/icon-staging.svg new file mode 100644 index 00000000000..350b9d4673d --- /dev/null +++ b/apps/sim/public/icon-staging.svg @@ -0,0 +1 @@ + \ No newline at end of file From 1682470bae2c6c3a84a0179bf8f938121144f9f2 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:13:01 -0700 Subject: [PATCH 2/7] fix(favicon): lighter pink/yellow hues, fix CI env-flags naming check - dev favicon: orange -> light pink - staging favicon: yellow -> lighter yellow (mark stays pixel-identical, background color only) - env-flags.ts's CI check requires every exported const to be is-/get- prefixed; deploymentEnv was a plain const. Converted to getDeploymentEnv(), matching the file's existing convention for non-boolean values (getCostMultiplier(), getAllowedIntegrationsFromEnv()). --- apps/sim/ee/whitelabeling/metadata.ts | 8 ++-- apps/sim/lib/core/config/env-flags.ts | 41 ++++++++++-------- apps/sim/next.config.ts | 6 +-- .../favicon-dev/android-chrome-192x192.png | Bin 5967 -> 6654 bytes .../favicon-dev/android-chrome-512x512.png | Bin 11762 -> 12440 bytes .../public/favicon-dev/apple-touch-icon.png | Bin 5542 -> 6181 bytes apps/sim/public/favicon-dev/favicon-16x16.png | Bin 391 -> 437 bytes apps/sim/public/favicon-dev/favicon-32x32.png | Bin 795 -> 878 bytes apps/sim/public/favicon-dev/favicon.ico | Bin 817 -> 900 bytes .../android-chrome-192x192.png | Bin 5997 -> 6318 bytes .../android-chrome-512x512.png | Bin 11660 -> 12192 bytes .../favicon-staging/apple-touch-icon.png | Bin 5576 -> 5917 bytes .../public/favicon-staging/favicon-16x16.png | Bin 390 -> 413 bytes .../public/favicon-staging/favicon-32x32.png | Bin 792 -> 841 bytes apps/sim/public/favicon-staging/favicon.ico | Bin 814 -> 863 bytes apps/sim/public/icon-dev.svg | 2 +- apps/sim/public/icon-staging.svg | 2 +- 17 files changed, 31 insertions(+), 28 deletions(-) diff --git a/apps/sim/ee/whitelabeling/metadata.ts b/apps/sim/ee/whitelabeling/metadata.ts index f89a3fb2731..1f79b252fa4 100644 --- a/apps/sim/ee/whitelabeling/metadata.ts +++ b/apps/sim/ee/whitelabeling/metadata.ts @@ -1,5 +1,5 @@ import type { Metadata } from 'next' -import { deploymentEnv } from '@/lib/core/config/env-flags' +import { getDeploymentEnv } from '@/lib/core/config/env-flags' import { getBaseUrl, SITE_URL } from '@/lib/core/utils/urls' import { getBrandConfig } from '@/ee/whitelabeling/branding' @@ -13,14 +13,14 @@ interface FaviconSet { } /** - * Same "sim" wordmark per {@link deploymentEnv}, background color only — + * Same "sim" wordmark per {@link getDeploymentEnv}, background color only — * so a dev/staging tab is never mistaken for prod at a glance. Ignored * entirely when `brand.faviconUrl` is set (a whitelabeled deployment's own * favicon always wins, regardless of which tier it's running on). Kept in * sync with `FAVICON_ICO_DESTINATIONS` in `next.config.ts`, which handles * the legacy `/favicon.ico` path the same way. */ -const ICON_SETS: Record = { +const ICON_SETS: Record, FaviconSet> = { development: { svg: '/icon-dev.svg', favicon16: '/favicon-dev/favicon-16x16.png', @@ -52,7 +52,7 @@ const ICON_SETS: Record = { */ export function generateBrandedMetadata(override: Partial = {}): Metadata { const brand = getBrandConfig() - const icons = ICON_SETS[deploymentEnv] + const icons = ICON_SETS[getDeploymentEnv()] const defaultTitle = brand.name const summaryFull = `Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM to create agents that automate real work — visually, conversationally, or with code. Trusted by over 100,000 builders — from startups to Fortune 500 companies. SOC2 compliant.` diff --git a/apps/sim/lib/core/config/env-flags.ts b/apps/sim/lib/core/config/env-flags.ts index 531a447810a..589da7fb306 100644 --- a/apps/sim/lib/core/config/env-flags.ts +++ b/apps/sim/lib/core/config/env-flags.ts @@ -30,28 +30,31 @@ export const isTest = env.NODE_ENV === 'test' * AWS Secrets Manager for dev/staging/production, so this reuses it rather * than inventing a second one. */ -const rawDeploymentEnv = - process.env.OTEL_DEPLOYMENT_ENVIRONMENT || - process.env.DEPLOYMENT_ENVIRONMENT || - (process.env.APPCONFIG_ENVIRONMENT === 'production' - ? 'prod' - : process.env.APPCONFIG_ENVIRONMENT) || - env.NODE_ENV || - 'development' +function resolveRawDeploymentEnv(): string { + return ( + process.env.OTEL_DEPLOYMENT_ENVIRONMENT || + process.env.DEPLOYMENT_ENVIRONMENT || + (process.env.APPCONFIG_ENVIRONMENT === 'production' + ? 'prod' + : process.env.APPCONFIG_ENVIRONMENT) || + env.NODE_ENV || + 'development' + ) +} /** * The deployment tier this build is running in, bucketed from - * {@link rawDeploymentEnv} to a fixed three-way set for UI-facing branches — - * currently just per-environment favicons, so it's obvious at a glance which - * tab is prod vs. a staging/local build. See `ee/whitelabeling/metadata.ts` - * and `next.config.ts`. - */ -export const deploymentEnv: 'development' | 'staging' | 'production' = - rawDeploymentEnv === 'staging' - ? 'staging' - : rawDeploymentEnv === 'prod' || rawDeploymentEnv === 'production' - ? 'production' - : 'development' + * {@link resolveRawDeploymentEnv} to a fixed three-way set for UI-facing + * branches — currently just per-environment favicons, so it's obvious at a + * glance which tab is prod vs. a staging/local build. See + * `ee/whitelabeling/metadata.ts` and `next.config.ts`. + */ +export function getDeploymentEnv(): 'development' | 'staging' | 'production' { + const raw = resolveRawDeploymentEnv() + if (raw === 'staging') return 'staging' + if (raw === 'prod' || raw === 'production') return 'production' + return 'development' +} /** * Is this the hosted version of the application. diff --git a/apps/sim/next.config.ts b/apps/sim/next.config.ts index 3641e236607..9932290898f 100644 --- a/apps/sim/next.config.ts +++ b/apps/sim/next.config.ts @@ -1,7 +1,7 @@ import path from 'node:path' import type { NextConfig } from 'next' import { env, isTruthy } from './lib/core/config/env' -import { deploymentEnv, isDev } from './lib/core/config/env-flags' +import { getDeploymentEnv, isDev } from './lib/core/config/env-flags' import { getChatEmbedCSPPolicy, getMainCSPPolicy, @@ -33,7 +33,7 @@ const minimalRegistryAlias: Record = useMinimalRegistry * `` tags Next renders from `generateBrandedMetadata()` * (`ee/whitelabeling/metadata.ts`) use the same per-environment set. */ -const FAVICON_ICO_DESTINATIONS: Record = { +const FAVICON_ICO_DESTINATIONS: Record, string> = { development: '/icon-dev.svg', staging: '/icon-staging.svg', production: '/icon.svg', @@ -451,7 +451,7 @@ const nextConfig: NextConfig = { return [ { source: '/favicon.ico', - destination: FAVICON_ICO_DESTINATIONS[deploymentEnv], + destination: FAVICON_ICO_DESTINATIONS[getDeploymentEnv()], }, { source: '/r/:shortCode', diff --git a/apps/sim/public/favicon-dev/android-chrome-192x192.png b/apps/sim/public/favicon-dev/android-chrome-192x192.png index 5fe8149bacea40429d5db87794b325d6e064fe77..e402a6191304e1124ef4904ae709ea8504760bd6 100644 GIT binary patch literal 6654 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 tqW<5mm&XB=iFc=|-h!%|AA_&pD!616{ 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 diff --git a/apps/sim/public/favicon-dev/apple-touch-icon.png b/apps/sim/public/favicon-dev/apple-touch-icon.png index f702551aedf0fc304b43e8a1259c6e6c5ac97df9..a1938cec1f2f94eb58787fb03fab6aa7e8f0c1f3 100644 GIT binary patch literal 6181 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 literal 5542 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 FV1n0j#0~%e delta 364 zcmV-y0h9i<1BU~UB!5mxL_t(|oVAj@N&`U<$7g0glHBEt_>F>Ml}ZaCg&^44`3Am# z&tvBU_ySsqjg{I8Vxb@ejU+-eclo-#9odZpHKYjWEIY+8fBwInS>(eCOcFFvH~fvj zGVpkT{NCq-NeRd}%PgQf42*z;BMu~qBvL`0JvLvHRD??8B!6iVc}a?frq01Kki?sp z_`KTMm=Ee*b6Ja%=T<#QD+|FzHQrw@Z7qh@SVHgM#Dpgg%}`OGDb4uw>Epd)Rzh`r z_qMk-b#&WcX7p4}KnQI3pgdF3;<}c!jnx8omy0_~#m(8m_G%PqV#7E@Vg?d$RZHSD zBZj=dyr8b(wq>vmxNmd9J%14RwP|!@_sw2;I@h<{F*cBd2tC80qE?zkO8gwFA3}Mq z0G>w+=}HVz6EH_wI*if9v2hH{!0!5r?;GUbiyLqa^SH|Yf4)z&YKy5Vs09@O0000< KMNUMnLSTZ260R)( diff --git a/apps/sim/public/favicon-dev/favicon-32x32.png b/apps/sim/public/favicon-dev/favicon-32x32.png index c13edee09cacfb947adeebe391e7169793a42042..bbb5019e77bbcbcd9d7d0659920f660968949240 100644 GIT binary patch delta 856 zcmV-e1E>6(2JQxsBYy)mNklYSV;?g02ZfCpO`OIjPPe#7EAQf+j=|J_)gLX4Rm5f#mu*?PZg%<1L^AGhOKN%h zX-{-|d1+B8F@L&e;E6#qyL_fLMrj2Ac>zd}G4>*r__}%T%T&B99H~G5WAmoQPos1D zhMot6z4g}vW#LHI)1L1B-mo2P+OW6n{eP z-O>9`-|hOAE8n%&eX`=roeo!dmwNsjN+sfM>g3J#oqx+V{=TbuQFQK_qq~!Cx^u_z z;~N{!cK>$b#s$j>X=C!f0T4hfKP;(?r-%2qH?3SyeQ?coZUr9n_eKK6f{78&t^IiU z>cuOG^0s|hd!_e!L(S$7%A!>jv9GS3?tb<+8E4Qq0HrjYPSwm?`cvJ$!=0@^-)OVA zb!7dwv42Q~G%D+1(6Wu2BuXlyLRJ6?dTx>%hclk*%$qGjf|Rj`&mS$X`t0iN=3Dir zmdskP=iDKUngJyQArndplmZ0;27Na&B_R6UNdVdy+X=V)b$R{|b@v|Mm8hjw(*hwz znKn8b`P?k##vk*14X;_mDD_5$zxiVQ{eeeokAKzMTogN@qjmd;pIr-pT1;>@`UnMZ zxER}7FfLxTas}i5$%x1q7u@Q5+3#u@E2(6ZCDO@(;lc87WN0KIn1}?62q9_d{+omCX7g7$0lp zwNYr4=|{~Uojp^ah?tfh1@M&gvz$qbL3E`z7EABd{gVU6Fu5hol;bYumJ>&hK1d2I iIt7?aQ-DcTaKQgF?}T+qBeL`W0000`Z~{=o8pT>}v9F@FF#?k0c$B#|UaCyuZf zOQzOSPeti5=&_=|0T2NKa7*w4fgF@zZ@;hmACEl^Eu+O9MTo!*hKNdMzyvbEXcM0U z;6~@@5WJX-_I(V`ttA=913shckiW6SirG>KrWA}X#MTm$nH&u^y&MlkZRCh7i;QBM zGQcnrmlp>^OMkZG_lO&>=lV_sj|RNcYYC5FUBlnXJz``b_F>W9XRwDSYX+uQdcQ>C zN}Z`LdeB>=j5NG}*JM=;x^YzO!klv*~JmY5!Ezc4%;RH4>N03E4fdbn9^7 z&ErjfF>-Y(UJ&e;a@!QbM%`i@V!{ z_eK|97R6E-CLDVAegZ|ayE$w02$6i?9)|+!ySzy zR}LPl@PFNWHR}*@blp)mB}ZU7TuKb4r><{KfFuHo^?r@i^^Q->uO|tTl1eNt5FH(C zYx}3Bzmp?yYusTwB#O&x&Hhgj`@+DK#j(iXkJ^I-U~#txO^!mBl1jWFRhKs1u~}-s zEO#000310RSK%00000AOLQW4=R5HHAzH4RCt{2m0M^OXB5Z3^Ic|U zFNtmvLJV8&7UK1x)mAFD!Gf3<@dn05Uwx3G;FYu$3;|y(_#je*fLKWtn^aIiOz=XA zL0al1)hJ40K@A2?tI2k=o1OVCr_62)YvK|G_bvaY@64GwzcYXS!@$VFPEttGf=(w> zfVY3p6yUu95V5cTi;MROKti-J+L-L(6yRCnMQ+#NXp8t~zjy}#B2s`*uqYIo#u>MS z{m0{b(Z*Hh?p}3*MapOj5VQiE@$3cxVF!hc8BLtVCr-DxNGtE+osPlOf7Kr?j8(*D z6qjvTx^8y)%tSKoa7$`=`)N;fdUHEb329^Uz5x(GEk7)&jHie9w>Pa^P&%-i zLV}dBhtD4^ulnrj?&e$drdH{>g~Q85i8@d)e=587rw|lqJ&1f#JdO zaAasCA()5+iwGfU>HeFHR}_~rpa3v1Jjj8Tgr;N0x4eKX0|`3*%HS$#&@jpb<5DY5 z86v8TT@-*bE|tvsA{ZZQ<+V|0l<7y!ADul@poo~39tH4}^s}5vi$QdyHx^6p)%}wL z#xS`h&6MLV=9Uvjk3L8WEII|4OjCeKRdB%nGw+0TN+YuL00000NkvXXu0mjfMZ>I` delta 789 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 G5B(1_((vQ} literal 5997 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 literal 11660 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

<)bI-{!Fkrw36ocZ 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 Mr~av0#xm@G037Jxb^rhX diff --git a/apps/sim/public/favicon-staging/favicon-16x16.png b/apps/sim/public/favicon-staging/favicon-16x16.png index 0fa3c7dd8c94701619c90dafdf252868cc373d53..4d88135a7cbf22a24d0b396630b8db757092a7ef 100644 GIT binary patch delta 386 zcmV-|0e$|41DykqB!6T{L_t(|oV`*#O9Md=-I?9Xop+ZHOdx1!BZ9;t3L=7}kXYH- z`nPQCEW}>ZnJyrSf51l4sBqDk5X|K+*%`ScXQE&c5VzRbnVmN?@9lzamc=3q7s?iY z10Z7NUjb?^Z)}*At3*JeO82td9*Jy}U7RlU*e`#NFZ!ER=MCsWvP_expU zkrYJbXQV;G-Ftoaqdx*-%aoRhen5R+M`H9wW&#DwaTwc(_rqg7*;a116GLNCQHMreunA0RSRK38beo&E7!>p?v}n(bZ^5ktjOo*!>BZM5FC% g;z=ZS|K;<20)1nZ1o1$?&j0`b07*qoM6N<$f+35wc>n+a delta 363 zcmV-x0hIoo1BL^TB!5jwL_t(|oV`*#Ps1<}z2`V_KBz!KSy-4rNJs^VZjoSR=}+K) zvG50AU_fF(0wxBkE?wDJ7^qMOC{1i9hn%L+p$wG}PqNRp-t)aX8@iv;G7w9#>2Cy8 zMa;hnYeNJAIWa(DcJnMUsR&AuTF2F`c^Pt;B7bZ_B?#A`B1f14x}R1| zen5|d@~&swJKpe(laMBsUWZj@*SqhP-6PrAlO|_@Is-F_0OvO*4iP6PG+#g1(TF!v zadv5rGkJQUxnz7>5+IxNN!MR(p*OIToB~OQ2Qu52?JbdIawUc-nlhTAh371dCya_z zL}7ru;Lp5n#$*QvzN`DE1{dIrJv~?3n?f6!6dZ>DsL-55cpq~sX%vlM3SW^+T{p3; zyDZ=qo=0W5=;3tjp=2`FC1fUB^Q>L;a8qM$ZpPfnZ2K>t?+c;(i0CXgm^T0b002ov JPDHLkV1hV~pYZ?y diff --git a/apps/sim/public/favicon-staging/favicon-32x32.png b/apps/sim/public/favicon-staging/favicon-32x32.png index 386682a32987abbcc21723c663209c02df2dc200..5ee6ff6bfe9d5a8d93aafeb768ba060b3e349c81 100644 GIT binary patch delta 819 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 Qi~s-t07*qoM6N<$f_YYXIsgCw diff --git a/apps/sim/public/icon-dev.svg b/apps/sim/public/icon-dev.svg index 8805cc3f5ff..d70aaa35860 100644 --- a/apps/sim/public/icon-dev.svg +++ b/apps/sim/public/icon-dev.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/apps/sim/public/icon-staging.svg b/apps/sim/public/icon-staging.svg index 350b9d4673d..6b5d56f222a 100644 --- a/apps/sim/public/icon-staging.svg +++ b/apps/sim/public/icon-staging.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 944c5e4110d85bb413a6ad2821590d194e1f7c83 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:27:03 -0700 Subject: [PATCH 3/7] fix(favicon): resolve deployment tier at request time, not build time Addresses review findings on PR #5588: - Cursor (Medium): next.config.ts's rewrites() runs once during the shared, environment-agnostic Docker build (docker/app.Dockerfile builds with dummy env values; bootstrap.ts hydrates process.env from AWS Secrets Manager only at container boot, after the build already ran) - so resolving getDeploymentEnv() inside next.config.ts baked in whichever tier happened to be active during that shared build, never the tier the container actually runs as. Fixed by rewriting /favicon.ico to a stable path (/api/favicon) and resolving the destination inside that route handler instead, which runs per-request at runtime like generateBrandedMetadata() already correctly does. Marked force-dynamic per Next's own docs: generated icon routes are statically cached by default unless they use a request-time API or dynamic config. - Greptile (P1): a whitelabeled deployment's favicon slots (16/32/192/512 PNGs, apple-touch-icon) fell back to the environment-tinted set instead of neutral branding when brand.faviconUrl was set. Now falls back to the production (neutral) asset set specifically for whitelabeled deployments, matching pre-PR behavior for those slots. - Greptile (P2, ico-serves-svg): verified via `git show origin/staging` that /favicon.ico -> /icon.svg is pre-existing, unchanged production behavior from before this PR - not addressed here, out of scope. Also: added app/api/favicon/route.ts to the check:api-validation INDIRECT_ZOD_ROUTES allowlist (no client-supplied input - only reads the server's own deployment-tier env var) and bumped the audit baseline. --- apps/sim/app/api/favicon/route.ts | 28 +++++++++++++++++++++++ apps/sim/ee/whitelabeling/metadata.ts | 6 ++++- apps/sim/next.config.ts | 20 ++++------------ scripts/check-api-validation-contracts.ts | 7 ++++-- 4 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 apps/sim/app/api/favicon/route.ts diff --git a/apps/sim/app/api/favicon/route.ts b/apps/sim/app/api/favicon/route.ts new file mode 100644 index 00000000000..127431d5c8f --- /dev/null +++ b/apps/sim/app/api/favicon/route.ts @@ -0,0 +1,28 @@ +import { type NextRequest, NextResponse } from 'next/server' +import { getDeploymentEnv } from '@/lib/core/config/env-flags' +import { withRouteHandler } from '@/lib/core/utils/with-route-handler' + +export const dynamic = 'force-dynamic' + +const FAVICON_DESTINATIONS: Record, string> = { + development: '/icon-dev.svg', + staging: '/icon-staging.svg', + production: '/icon.svg', +} + +/** + * Redirect target for the legacy `/favicon.ico` path (rewritten here in + * `next.config.ts`), resolved per-request rather than baked into + * `next.config.ts`'s `rewrites()` directly. This app's Docker image is built + * once with dummy env values and promoted through dev/staging/production — + * `bootstrap.ts` hydrates `process.env` from AWS Secrets Manager at container + * boot, after the build already ran (`docker/app.Dockerfile`) — so a + * same-process-lifetime decision like `getDeploymentEnv()` must be evaluated + * here, at request time, not in `next.config.ts`, which only runs once during + * that shared build and would freeze whichever tier happened to be active + * then (never the tier the container actually ends up running as). + */ +export const GET = withRouteHandler(async (request: NextRequest) => { + const destination = FAVICON_DESTINATIONS[getDeploymentEnv()] + return NextResponse.redirect(new URL(destination, request.url)) +}) diff --git a/apps/sim/ee/whitelabeling/metadata.ts b/apps/sim/ee/whitelabeling/metadata.ts index 1f79b252fa4..8a0c4f1e1b9 100644 --- a/apps/sim/ee/whitelabeling/metadata.ts +++ b/apps/sim/ee/whitelabeling/metadata.ts @@ -52,7 +52,11 @@ const ICON_SETS: Record, FaviconSet> = { */ export function generateBrandedMetadata(override: Partial = {}): Metadata { const brand = getBrandConfig() - const icons = ICON_SETS[getDeploymentEnv()] + // A whitelabeled deployment's favicon slots should read as the tenant's own + // brand, never an internal Sim dev/staging color — fall back to production's + // neutral assets (matching pre-environment-favicon behavior) for the sizes + // `brand.faviconUrl` doesn't cover, instead of the environment-tinted set. + const icons = ICON_SETS[brand.faviconUrl ? 'production' : getDeploymentEnv()] const defaultTitle = brand.name const summaryFull = `Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM to create agents that automate real work — visually, conversationally, or with code. Trusted by over 100,000 builders — from startups to Fortune 500 companies. SOC2 compliant.` diff --git a/apps/sim/next.config.ts b/apps/sim/next.config.ts index 9932290898f..8e6712cb775 100644 --- a/apps/sim/next.config.ts +++ b/apps/sim/next.config.ts @@ -1,7 +1,7 @@ import path from 'node:path' import type { NextConfig } from 'next' import { env, isTruthy } from './lib/core/config/env' -import { getDeploymentEnv, isDev } from './lib/core/config/env-flags' +import { isDev } from './lib/core/config/env-flags' import { getChatEmbedCSPPolicy, getMainCSPPolicy, @@ -26,19 +26,6 @@ const minimalRegistryAlias: Record = useMinimalRegistry } : {} -/** - * Per-environment favicon for `/favicon.ico` requests (the legacy path browsers - * probe automatically) — same wordmark mark as production, different background - * color, so a dev/staging tab is never mistaken for prod at a glance. The - * `` tags Next renders from `generateBrandedMetadata()` - * (`ee/whitelabeling/metadata.ts`) use the same per-environment set. - */ -const FAVICON_ICO_DESTINATIONS: Record, string> = { - development: '/icon-dev.svg', - staging: '/icon-staging.svg', - production: '/icon.svg', -} - const nextConfig: NextConfig = { devIndicators: false, poweredByHeader: false, @@ -450,8 +437,11 @@ const nextConfig: NextConfig = { async rewrites() { return [ { + // Resolved per-request in app/api/favicon/route.ts, not here — see + // that file's TSDoc for why: this config only runs once during the + // shared, environment-agnostic Docker build. source: '/favicon.ico', - destination: FAVICON_ICO_DESTINATIONS[getDeploymentEnv()], + destination: '/api/favicon', }, { source: '/r/:shortCode', diff --git a/scripts/check-api-validation-contracts.ts b/scripts/check-api-validation-contracts.ts index d8694b3f6bc..bbc209f93d9 100644 --- a/scripts/check-api-validation-contracts.ts +++ b/scripts/check-api-validation-contracts.ts @@ -9,8 +9,8 @@ const QUERY_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/queries') const SELECTOR_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/selectors') const BASELINE = { - totalRoutes: 927, - zodRoutes: 927, + totalRoutes: 928, + zodRoutes: 928, nonZodRoutes: 0, } as const @@ -55,6 +55,9 @@ const INDIRECT_ZOD_ROUTES = new Set([ // tokens and there are no params, query, or body to validate. Previously had // no-op `validateSchema(noInputSchema, {})` guards. 'apps/sim/app/api/health/route.ts', + // Redirect target for the legacy /favicon.ico rewrite in next.config.ts — + // reads only the server's own deployment-tier env var, no params/query/body. + 'apps/sim/app/api/favicon/route.ts', 'apps/sim/app/api/settings/allowed-providers/route.ts', 'apps/sim/app/api/settings/allowed-integrations/route.ts', 'apps/sim/app/api/settings/allowed-mcp-domains/route.ts', From 1833d928b78f092c14609e651e29581026910ca8 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:40:26 -0700 Subject: [PATCH 4/7] fix(favicon): resolve metadata at request time, fully honor whitelabel favicon Addresses the second round of review findings on PR #5588: - Cursor (High): app/layout.tsx exported a static `export const metadata = generateBrandedMetadata()`. Next.js treats a static metadata object as truly constant (eligible for build-time resolution on any statically-rendered route sharing the layout), so it doesn't know this one secretly depends on process.env via getDeploymentEnv() - same bake-in risk already fixed for next.config.ts. Converted to generateMetadata(), the documented way to force per-request resolution. - Greptile (P1): the earlier whitelabel fallback fixed the *tint* but not the underlying precedence gap - Sim's exact-size PNG/apple entries were still emitted alongside the tenant's generic sizes:'any' entry, and browsers can prefer the more specific size match. Now the tenant favicon fully replaces every icon slot instead of being appended alongside Sim's. - Cursor (Medium): app/api/favicon/route.ts never checked brand.faviconUrl, so a whitelabeled dev/staging deployment still served Sim's tinted icon at the legacy /favicon.ico path. Now checks brand.faviconUrl first, matching generateBrandedMetadata()'s precedence. --- apps/sim/app/api/favicon/route.ts | 8 ++++++- apps/sim/app/layout.tsx | 14 +++++++++++- apps/sim/ee/whitelabeling/metadata.ts | 33 +++++++++++++-------------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/apps/sim/app/api/favicon/route.ts b/apps/sim/app/api/favicon/route.ts index 127431d5c8f..94a6ef74081 100644 --- a/apps/sim/app/api/favicon/route.ts +++ b/apps/sim/app/api/favicon/route.ts @@ -1,6 +1,7 @@ import { type NextRequest, NextResponse } from 'next/server' import { getDeploymentEnv } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { getBrandConfig } from '@/ee/whitelabeling/branding' export const dynamic = 'force-dynamic' @@ -21,8 +22,13 @@ const FAVICON_DESTINATIONS: Record, string> * here, at request time, not in `next.config.ts`, which only runs once during * that shared build and would freeze whichever tier happened to be active * then (never the tier the container actually ends up running as). + * + * A whitelabeled deployment's own favicon always wins here too, matching + * `generateBrandedMetadata()` (`ee/whitelabeling/metadata.ts`) — a tenant on + * a dev/staging environment should never see Sim's internal tinted mark. */ export const GET = withRouteHandler(async (request: NextRequest) => { - const destination = FAVICON_DESTINATIONS[getDeploymentEnv()] + const brand = getBrandConfig() + const destination = brand.faviconUrl || FAVICON_DESTINATIONS[getDeploymentEnv()] return NextResponse.redirect(new URL(destination, request.url)) }) diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index baf60659e7e..b6239d16214 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -24,7 +24,19 @@ export const viewport: Viewport = { ], } -export const metadata: Metadata = generateBrandedMetadata() +/** + * Not a static `export const metadata` object: {@link generateBrandedMetadata} + * reads `getDeploymentEnv()` for the favicon set, which depends on + * `process.env` being populated by `bootstrap.ts`'s runtime secrets load. A + * static object is resolved once at module-evaluation time and Next.js treats + * it as truly constant (eligible for build-time resolution on any + * statically-rendered route sharing this layout) — `generateMetadata()` + * forces the same per-request resolution `app/api/favicon/route.ts` already + * uses. + */ +export function generateMetadata(): Metadata { + return generateBrandedMetadata() +} const GTM_ID = 'GTM-T7PHSRX5' as const const GA_ID = 'G-DR7YBE70VS' as const diff --git a/apps/sim/ee/whitelabeling/metadata.ts b/apps/sim/ee/whitelabeling/metadata.ts index 8a0c4f1e1b9..3896b949d60 100644 --- a/apps/sim/ee/whitelabeling/metadata.ts +++ b/apps/sim/ee/whitelabeling/metadata.ts @@ -139,23 +139,22 @@ export function generateBrandedMetadata(override: Partial = {}): Metad }, manifest: '/manifest.webmanifest', icons: { - icon: [ - ...(brand.faviconUrl ? [] : [{ url: icons.svg, type: 'image/svg+xml', sizes: 'any' }]), - { url: icons.favicon16, sizes: '16x16', type: 'image/png' }, - { url: icons.favicon32, sizes: '32x32', type: 'image/png' }, - { - url: icons.android192, - sizes: '192x192', - type: 'image/png', - }, - { - url: icons.android512, - sizes: '512x512', - type: 'image/png', - }, - ...(brand.faviconUrl ? [{ url: brand.faviconUrl, sizes: 'any', type: 'image/png' }] : []), - ], - apple: icons.apple, + // A whitelabeled deployment only ever supplies one favicon URL (no + // multi-size set of its own) - emitting Sim's exact-size PNG/apple + // entries alongside it would let browsers prefer those more specific + // sizes over the tenant's generic `sizes: 'any'` entry, showing Sim + // branding instead. So the tenant favicon fully replaces every slot + // rather than being appended to Sim's. + icon: brand.faviconUrl + ? [{ url: brand.faviconUrl, sizes: 'any', type: 'image/png' }] + : [ + { url: icons.svg, type: 'image/svg+xml', sizes: 'any' }, + { url: icons.favicon16, sizes: '16x16', type: 'image/png' }, + { url: icons.favicon32, sizes: '32x32', type: 'image/png' }, + { url: icons.android192, sizes: '192x192', type: 'image/png' }, + { url: icons.android512, sizes: '512x512', type: 'image/png' }, + ], + apple: brand.faviconUrl || icons.apple, shortcut: brand.faviconUrl || icons.svg, }, appleWebApp: { From 5412f705d63fad01057495779ce9f616f4cb378c Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 21:50:06 -0700 Subject: [PATCH 5/7] refactor(favicon): eliminate duplicate icon-set map, add getDeploymentEnv() test coverage Self-review pass, not a review-comment fix: - app/api/favicon/route.ts maintained its own env-to-svg-path map (FAVICON_DESTINATIONS) duplicating ICON_SETS in ee/whitelabeling/metadata.ts. The two could silently drift apart if an asset path ever changed in only one place. Exported ICON_SETS from metadata.ts (and the ee/whitelabeling barrel) and had the route reuse it directly instead. - Added lib/core/config/env-flags.test.ts covering getDeploymentEnv()'s resolution chain: each real AWS Secrets Manager value (dev/staging/prod), the APPCONFIG_ENVIRONMENT production->prod mapping, the NODE_ENV fallback, precedence ordering between the three signals, and an unrecognized-value case bucketing safely to development rather than throwing. This logic went through three rounds of review fixes: worth a regression net now that it's settled. --- apps/sim/app/api/favicon/route.ts | 18 ++--- apps/sim/ee/whitelabeling/index.ts | 2 +- apps/sim/ee/whitelabeling/metadata.ts | 9 +-- apps/sim/lib/core/config/env-flags.test.ts | 78 ++++++++++++++++++++++ 4 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 apps/sim/lib/core/config/env-flags.test.ts diff --git a/apps/sim/app/api/favicon/route.ts b/apps/sim/app/api/favicon/route.ts index 94a6ef74081..275f2d89439 100644 --- a/apps/sim/app/api/favicon/route.ts +++ b/apps/sim/app/api/favicon/route.ts @@ -1,16 +1,10 @@ import { type NextRequest, NextResponse } from 'next/server' import { getDeploymentEnv } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { getBrandConfig } from '@/ee/whitelabeling/branding' +import { getBrandConfig, ICON_SETS } from '@/ee/whitelabeling' export const dynamic = 'force-dynamic' -const FAVICON_DESTINATIONS: Record, string> = { - development: '/icon-dev.svg', - staging: '/icon-staging.svg', - production: '/icon.svg', -} - /** * Redirect target for the legacy `/favicon.ico` path (rewritten here in * `next.config.ts`), resolved per-request rather than baked into @@ -23,12 +17,14 @@ const FAVICON_DESTINATIONS: Record, string> * that shared build and would freeze whichever tier happened to be active * then (never the tier the container actually ends up running as). * - * A whitelabeled deployment's own favicon always wins here too, matching - * `generateBrandedMetadata()` (`ee/whitelabeling/metadata.ts`) — a tenant on - * a dev/staging environment should never see Sim's internal tinted mark. + * Reuses {@link ICON_SETS} from `ee/whitelabeling/metadata.ts` rather than + * maintaining a second env-to-path map here, so the two can't drift apart. A + * whitelabeled deployment's own favicon always wins here too, matching + * `generateBrandedMetadata()` — a tenant on a dev/staging environment should + * never see Sim's internal tinted mark. */ export const GET = withRouteHandler(async (request: NextRequest) => { const brand = getBrandConfig() - const destination = brand.faviconUrl || FAVICON_DESTINATIONS[getDeploymentEnv()] + const destination = brand.faviconUrl || ICON_SETS[getDeploymentEnv()].svg return NextResponse.redirect(new URL(destination, request.url)) }) diff --git a/apps/sim/ee/whitelabeling/index.ts b/apps/sim/ee/whitelabeling/index.ts index 6cd22b7b1c3..0d7ff675d0e 100644 --- a/apps/sim/ee/whitelabeling/index.ts +++ b/apps/sim/ee/whitelabeling/index.ts @@ -2,5 +2,5 @@ export type { OrganizationWhitelabelSettings } from '@/lib/branding/types' export type { BrandConfig, ThemeColors } from './branding' export { getBrandConfig, useBrandConfig } from './branding' export { generateThemeCSS } from './inject-theme' -export { generateBrandedMetadata, generateStructuredData } from './metadata' +export { generateBrandedMetadata, generateStructuredData, ICON_SETS } from './metadata' export { generateOrgThemeCSS, mergeOrgBrandConfig } from './org-branding-utils' diff --git a/apps/sim/ee/whitelabeling/metadata.ts b/apps/sim/ee/whitelabeling/metadata.ts index 3896b949d60..ad92c0b0009 100644 --- a/apps/sim/ee/whitelabeling/metadata.ts +++ b/apps/sim/ee/whitelabeling/metadata.ts @@ -16,11 +16,12 @@ interface FaviconSet { * Same "sim" wordmark per {@link getDeploymentEnv}, background color only — * so a dev/staging tab is never mistaken for prod at a glance. Ignored * entirely when `brand.faviconUrl` is set (a whitelabeled deployment's own - * favicon always wins, regardless of which tier it's running on). Kept in - * sync with `FAVICON_ICO_DESTINATIONS` in `next.config.ts`, which handles - * the legacy `/favicon.ico` path the same way. + * favicon always wins, regardless of which tier it's running on). Exported + * for `app/api/favicon/route.ts` (the legacy `/favicon.ico` redirect target) + * to reuse `.svg` from, so the two never drift out of sync the way two + * separately-maintained copies could. */ -const ICON_SETS: Record, FaviconSet> = { +export const ICON_SETS: Record, FaviconSet> = { development: { svg: '/icon-dev.svg', favicon16: '/favicon-dev/favicon-16x16.png', diff --git a/apps/sim/lib/core/config/env-flags.test.ts b/apps/sim/lib/core/config/env-flags.test.ts new file mode 100644 index 00000000000..0f8ad38aa93 --- /dev/null +++ b/apps/sim/lib/core/config/env-flags.test.ts @@ -0,0 +1,78 @@ +/** + * @vitest-environment node + */ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +const { envRef } = vi.hoisted(() => ({ + envRef: { NODE_ENV: 'development' as string | undefined }, +})) + +vi.mock('@/lib/core/config/env', () => ({ + get env() { + return envRef + }, + getEnv: (key: string) => process.env[key], + isFalsy: (v: unknown) => v === false || v === 'false' || v === '0', + isTruthy: (v: unknown) => v === true || v === 'true' || v === '1', +})) + +import { getDeploymentEnv } from '@/lib/core/config/env-flags' + +describe('getDeploymentEnv', () => { + const ENV_KEYS = [ + 'OTEL_DEPLOYMENT_ENVIRONMENT', + 'DEPLOYMENT_ENVIRONMENT', + 'APPCONFIG_ENVIRONMENT', + ] + + beforeEach(() => { + for (const key of ENV_KEYS) delete process.env[key] + envRef.NODE_ENV = 'development' + }) + + afterEach(() => { + for (const key of ENV_KEYS) delete process.env[key] + }) + + it('resolves the dev tier from OTEL_DEPLOYMENT_ENVIRONMENT=dev', () => { + process.env.OTEL_DEPLOYMENT_ENVIRONMENT = 'dev' + expect(getDeploymentEnv()).toBe('development') + }) + + it('resolves the staging tier from OTEL_DEPLOYMENT_ENVIRONMENT=staging', () => { + process.env.OTEL_DEPLOYMENT_ENVIRONMENT = 'staging' + expect(getDeploymentEnv()).toBe('staging') + }) + + it('resolves the production tier from OTEL_DEPLOYMENT_ENVIRONMENT=prod', () => { + process.env.OTEL_DEPLOYMENT_ENVIRONMENT = 'prod' + expect(getDeploymentEnv()).toBe('production') + }) + + it('maps APPCONFIG_ENVIRONMENT=production to the production tier when OTEL var is unset', () => { + process.env.APPCONFIG_ENVIRONMENT = 'production' + expect(getDeploymentEnv()).toBe('production') + }) + + it('falls back to NODE_ENV when no deployment-tier env var is set', () => { + envRef.NODE_ENV = 'production' + expect(getDeploymentEnv()).toBe('production') + }) + + it('defaults to development when nothing is set at all', () => { + envRef.NODE_ENV = undefined + expect(getDeploymentEnv()).toBe('development') + }) + + it('prefers OTEL_DEPLOYMENT_ENVIRONMENT over DEPLOYMENT_ENVIRONMENT and APPCONFIG_ENVIRONMENT', () => { + process.env.OTEL_DEPLOYMENT_ENVIRONMENT = 'staging' + process.env.DEPLOYMENT_ENVIRONMENT = 'prod' + process.env.APPCONFIG_ENVIRONMENT = 'production' + expect(getDeploymentEnv()).toBe('staging') + }) + + it('buckets an unrecognized tier value to development rather than throwing', () => { + process.env.OTEL_DEPLOYMENT_ENVIRONMENT = 'some-future-tier' + expect(getDeploymentEnv()).toBe('development') + }) +}) From 37a3b05e1ac3ecf2fc3ca55d50619e2836425920 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 22:07:45 -0700 Subject: [PATCH 6/7] fix(favicon): close static/ISR bake-in gap, fix manifest whitelabel leak Addresses the third round of review findings on PR #5588: - Cursor (Medium): generateMetadata() alone does not force per-request evaluation - only the overall page being dynamic does, and a plain process.env read is not a Next.js "dynamic signal" Next can detect. Verified this doesn't matter for any route TODAY (0 of 1007 real page routes are static/ISR-eligible - only non-HTML RSS/sitemap/robots/OG files are), but it was a latent gap: any future static or ISR page added under the root layout would silently get build-time (production-tier) favicon metadata baked in, with no error. Added `export const dynamic = 'force-dynamic'` to app/layout.tsx, matching the same declaration already on app/manifest.ts and app/api/favicon/route.ts. Verified via full build that the 9 legitimately-static routes (RSS/sitemap/robots/OG-image files, which don't render through the root layout's page tree) are unaffected - same count, same routes, before and after. - Greptile (P1, reported as two separate threads): app/manifest.ts (PWA install/home-screen icons) never checked brand.faviconUrl at all, so a whitelabeled deployment would still show Sim's icon when installed even after the HTML favicon was fixed. Now uses brand.faviconUrl when set, same precedence as generateBrandedMetadata(). - Cursor (Low): the `brand.faviconUrl ? 'production' : getDeploymentEnv()` ternary computed a value never actually read when brand.faviconUrl is set (every consumer already short-circuits on brand.faviconUrl first). Simplified to always resolve the environment tier. --- apps/sim/app/layout.tsx | 20 +++++++++++++- apps/sim/app/manifest.ts | 39 +++++++++++++++------------ apps/sim/ee/whitelabeling/metadata.ts | 9 +++---- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index b6239d16214..4b95782a638 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -24,6 +24,22 @@ export const viewport: Viewport = { ], } +/** + * Forces every route under this layout to render dynamically. Every real page + * in this app already renders dynamically today (session/workspace state), so + * this changes nothing currently — but it's the difference between "happens + * to be true" and "guaranteed": {@link generateBrandedMetadata} reads + * `getDeploymentEnv()` for the favicon set, which depends on `process.env` + * being populated by `bootstrap.ts`'s runtime secrets load, and + * `generateMetadata()` alone does not force per-request evaluation — Next + * still prerenders it at build time for any route that's otherwise static or + * ISR-eligible. Without this, a future static/ISR page added under this + * layout would silently get build-time (production-tier) favicon metadata + * baked in, with no error. Matches the `force-dynamic` already declared on + * `app/manifest.ts` and `app/api/favicon/route.ts`. + */ +export const dynamic = 'force-dynamic' + /** * Not a static `export const metadata` object: {@link generateBrandedMetadata} * reads `getDeploymentEnv()` for the favicon set, which depends on @@ -32,7 +48,9 @@ export const viewport: Viewport = { * it as truly constant (eligible for build-time resolution on any * statically-rendered route sharing this layout) — `generateMetadata()` * forces the same per-request resolution `app/api/favicon/route.ts` already - * uses. + * uses. Paired with the `dynamic = 'force-dynamic'` export above, which + * guarantees that resolution actually happens per-request rather than only + * "happening to" because every current page is otherwise dynamic. */ export function generateMetadata(): Metadata { return generateBrandedMetadata() diff --git a/apps/sim/app/manifest.ts b/apps/sim/app/manifest.ts index 23e600614a0..ccdae3ef0dd 100644 --- a/apps/sim/app/manifest.ts +++ b/apps/sim/app/manifest.ts @@ -20,23 +20,28 @@ export default function manifest(): MetadataRoute.Manifest { background_color: '#ffffff', theme_color: brand.theme?.primaryColor || '#33C482', orientation: 'portrait-primary', - icons: [ - { - src: '/favicon/android-chrome-192x192.png', - sizes: '192x192', - type: 'image/png', - }, - { - src: '/favicon/android-chrome-512x512.png', - sizes: '512x512', - type: 'image/png', - }, - { - src: '/favicon/apple-touch-icon.png', - sizes: '180x180', - type: 'image/png', - }, - ], + // A whitelabeled deployment's install/home-screen icon should be the + // tenant's own brand, not Sim's — same precedence as the HTML favicon + // slots in generateBrandedMetadata() (ee/whitelabeling/metadata.ts). + icons: brand.faviconUrl + ? [{ src: brand.faviconUrl, sizes: 'any', type: 'image/png' }] + : [ + { + src: '/favicon/android-chrome-192x192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/favicon/android-chrome-512x512.png', + sizes: '512x512', + type: 'image/png', + }, + { + src: '/favicon/apple-touch-icon.png', + sizes: '180x180', + type: 'image/png', + }, + ], categories: ['productivity', 'developer', 'business'], shortcuts: [ { diff --git a/apps/sim/ee/whitelabeling/metadata.ts b/apps/sim/ee/whitelabeling/metadata.ts index ad92c0b0009..ff3acdeeaa4 100644 --- a/apps/sim/ee/whitelabeling/metadata.ts +++ b/apps/sim/ee/whitelabeling/metadata.ts @@ -53,11 +53,10 @@ export const ICON_SETS: Record, FaviconSet> */ export function generateBrandedMetadata(override: Partial = {}): Metadata { const brand = getBrandConfig() - // A whitelabeled deployment's favicon slots should read as the tenant's own - // brand, never an internal Sim dev/staging color — fall back to production's - // neutral assets (matching pre-environment-favicon behavior) for the sizes - // `brand.faviconUrl` doesn't cover, instead of the environment-tinted set. - const icons = ICON_SETS[brand.faviconUrl ? 'production' : getDeploymentEnv()] + // Only read when brand.faviconUrl is unset — every icon/apple/shortcut slot + // below short-circuits on brand.faviconUrl first when it's set, so this + // never needs to reflect the whitelabel case. + const icons = ICON_SETS[getDeploymentEnv()] const defaultTitle = brand.name const summaryFull = `Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Connect 1,000+ integrations and every major LLM to create agents that automate real work — visually, conversationally, or with code. Trusted by over 100,000 builders — from startups to Fortune 500 companies. SOC2 compliant.` From 1e42a73a3e0ee48b482203d2f29f1b18fe2d7eef Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 22:43:44 -0700 Subject: [PATCH 7/7] fix(favicon): revert marketing-ISR-breaking force-dynamic, fix manifest env-tint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses the fourth round of review findings on PR #5588: - Cursor (High, confirmed via testing, not just code review): the previous commit's `export const dynamic = 'force-dynamic'` on app/layout.tsx would have forced the entire marketing site ((landing) route group - blog/library posts, changelog, solutions pages, all with their own `revalidate` exports) into per-request rendering, breaking their Lighthouse/LCP budget. My earlier "verified via build, no regression" claim was itself wrong: my local build masked this because NEXT_PUBLIC_APP_URL=localhost makes isHosted() false, which makes app/layout.tsx render next-runtime-env's RuntimePublicEnvScript - which unconditionally calls unstable_noStore() - already forcing marketing pages dynamic before my change even ran, for a completely unrelated pre-existing reason. Rebuilt with NEXT_PUBLIC_APP_URL=https://www.sim.ai (matching real hosted deployments, isHosted() true, the safe script path) to get an unmasked answer: confirmed force-dynamic was the actual regression (marketing pages went from ● to ƒ), and confirmed the revert restores them to ○ with their normal 1h revalidate window. Documented the accepted tradeoff instead: marketing-page favicon metadata may lag by up to one revalidate window after a deploy (bounded, self-healing at the next ISR regeneration, which runs in the live server process after bootstrap.ts has loaded secrets) - the actual workspace app (this feature's real audience) is already fully dynamic today (session/auth), so it needs no explicit marker. - Cursor (Medium): app/manifest.ts's non-whitelabeled branch still hardcoded production favicon paths instead of ICON_SETS[getDeploymentEnv()], so PWA install/home-screen icons stayed production-tinted while the HTML favicon was correctly env-tinted. Now uses the same per-tier set. --- apps/sim/app/layout.tsx | 39 +++++++++++++++++---------------------- apps/sim/app/manifest.ts | 28 ++++++++++------------------ 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index 4b95782a638..358ba0d5fa7 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -24,33 +24,28 @@ export const viewport: Viewport = { ], } -/** - * Forces every route under this layout to render dynamically. Every real page - * in this app already renders dynamically today (session/workspace state), so - * this changes nothing currently — but it's the difference between "happens - * to be true" and "guaranteed": {@link generateBrandedMetadata} reads - * `getDeploymentEnv()` for the favicon set, which depends on `process.env` - * being populated by `bootstrap.ts`'s runtime secrets load, and - * `generateMetadata()` alone does not force per-request evaluation — Next - * still prerenders it at build time for any route that's otherwise static or - * ISR-eligible. Without this, a future static/ISR page added under this - * layout would silently get build-time (production-tier) favicon metadata - * baked in, with no error. Matches the `force-dynamic` already declared on - * `app/manifest.ts` and `app/api/favicon/route.ts`. - */ -export const dynamic = 'force-dynamic' - /** * Not a static `export const metadata` object: {@link generateBrandedMetadata} * reads `getDeploymentEnv()` for the favicon set, which depends on * `process.env` being populated by `bootstrap.ts`'s runtime secrets load. A * static object is resolved once at module-evaluation time and Next.js treats - * it as truly constant (eligible for build-time resolution on any - * statically-rendered route sharing this layout) — `generateMetadata()` - * forces the same per-request resolution `app/api/favicon/route.ts` already - * uses. Paired with the `dynamic = 'force-dynamic'` export above, which - * guarantees that resolution actually happens per-request rather than only - * "happening to" because every current page is otherwise dynamic. + * it as truly constant (eligible for build-time resolution) — + * `generateMetadata()` at least makes resolution part of the page's own + * render rather than a frozen module-level value. + * + * Deliberately NOT paired with `export const dynamic = 'force-dynamic'` on + * this (root) layout: every `(landing)` marketing page sets its own + * `revalidate` and relies on being statically generated / + * incrementally revalidated for its Lighthouse/LCP budget (see + * `app/(landing)/CLAUDE.md`) — forcing the root layout dynamic would force + * the entire marketing site dynamic too, which is a much larger regression + * than a favicon staying on its previous tier for up to one revalidate + * window after a deploy. The actual workspace app (this feature's real + * audience) is already fully dynamic today (session/auth), so + * `generateMetadata()` already resolves per-request there without needing + * the marker. Marketing pages accept bounded staleness instead: the favicon + * self-corrects at the next ISR regeneration, which runs in the live server + * process (after `bootstrap.ts` has loaded secrets), not at build time. */ export function generateMetadata(): Metadata { return generateBrandedMetadata() diff --git a/apps/sim/app/manifest.ts b/apps/sim/app/manifest.ts index ccdae3ef0dd..4e85e36d2ba 100644 --- a/apps/sim/app/manifest.ts +++ b/apps/sim/app/manifest.ts @@ -1,10 +1,12 @@ import type { MetadataRoute } from 'next' -import { getBrandConfig } from '@/ee/whitelabeling' +import { getDeploymentEnv } from '@/lib/core/config/env-flags' +import { getBrandConfig, ICON_SETS } from '@/ee/whitelabeling' export const dynamic = 'force-dynamic' export default function manifest(): MetadataRoute.Manifest { const brand = getBrandConfig() + const icons = ICON_SETS[getDeploymentEnv()] return { name: @@ -21,26 +23,16 @@ export default function manifest(): MetadataRoute.Manifest { theme_color: brand.theme?.primaryColor || '#33C482', orientation: 'portrait-primary', // A whitelabeled deployment's install/home-screen icon should be the - // tenant's own brand, not Sim's — same precedence as the HTML favicon - // slots in generateBrandedMetadata() (ee/whitelabeling/metadata.ts). + // tenant's own brand, not Sim's; otherwise it's the same per-environment + // set as the HTML favicon slots in generateBrandedMetadata() + // (ee/whitelabeling/metadata.ts), so a staging/dev PWA install doesn't + // look like prod either. icons: brand.faviconUrl ? [{ src: brand.faviconUrl, sizes: 'any', type: 'image/png' }] : [ - { - src: '/favicon/android-chrome-192x192.png', - sizes: '192x192', - type: 'image/png', - }, - { - src: '/favicon/android-chrome-512x512.png', - sizes: '512x512', - type: 'image/png', - }, - { - src: '/favicon/apple-touch-icon.png', - sizes: '180x180', - type: 'image/png', - }, + { src: icons.android192, sizes: '192x192', type: 'image/png' }, + { src: icons.android512, sizes: '512x512', type: 'image/png' }, + { src: icons.apple, sizes: '180x180', type: 'image/png' }, ], categories: ['productivity', 'developer', 'business'], shortcuts: [