diff --git a/packages/app/src/constants/platform.ts b/packages/app/src/constants/platform.ts index 97fb6d932..3dfcabe6a 100644 --- a/packages/app/src/constants/platform.ts +++ b/packages/app/src/constants/platform.ts @@ -10,6 +10,7 @@ import { isElectronRuntime, isElectronRuntimeMac } from "@/desktop/host"; // Default is cross-platform. Gate only when you must: // isWeb → DOM APIs (document, window,
, addEventListener) // isNative → Native-only APIs (Haptics, StatusBar, push tokens, camera) +// isDev → Development-only diagnostics and instrumentation // isElectron → Desktop wrapper features (file dialogs, titlebar, updates) // // For layout decisions, use useIsCompactFormFactor() from constants/layout.ts. @@ -22,6 +23,9 @@ export const isWeb = Platform.OS === "web"; /** iOS or Android — the JS runtime is React Native. */ export const isNative = Platform.OS !== "web"; +/** Development build/runtime — true in Metro dev bundles, false in production. */ +export const isDev = Boolean((globalThis as { __DEV__?: boolean }).__DEV__); + // --------------------------------------------------------------------------- // Electron detection (cached — only caches `true`, keeps checking if false // because the desktop bridge may load after initial module evaluation) diff --git a/packages/app/src/runtime/host-runtime.ts b/packages/app/src/runtime/host-runtime.ts index 562bc278e..e02390952 100644 --- a/packages/app/src/runtime/host-runtime.ts +++ b/packages/app/src/runtime/host-runtime.ts @@ -30,6 +30,7 @@ import { buildLocalDaemonTransportUrl, createDesktopLocalDaemonTransportFactory, } from "@/desktop/daemon/desktop-daemon-transport"; +import { isDev } from "@/constants/platform"; import { applyFetchedAgentDirectory } from "@/utils/agent-directory-sync"; import { useSessionStore, type Agent } from "@/stores/session-store"; @@ -433,6 +434,7 @@ function createDefaultDeps(): HostRuntimeControllerDeps { clientType: "mobile" as const, appVersion: resolveAppVersion() ?? undefined, runtimeGeneration, + ...(isDev ? { runtimeMetricsIntervalMs: 10_000 } : {}), }; if (connection.type === "directSocket" || connection.type === "directPipe") { return new DaemonClient({ diff --git a/packages/app/src/utils/scroll-jank-investigation.ts b/packages/app/src/utils/scroll-jank-investigation.ts index 50d66765b..2582a79b5 100644 --- a/packages/app/src/utils/scroll-jank-investigation.ts +++ b/packages/app/src/utils/scroll-jank-investigation.ts @@ -1,4 +1,4 @@ -import { isWeb } from "@/constants/platform"; +import { isDev, isWeb } from "@/constants/platform"; type ListenerStats = { adds: number; @@ -91,7 +91,6 @@ const SOURCE_LABEL = "[ScrollJankInvestigation]"; function shouldInstall(): boolean { const runtime = globalThis as ScrollInvestigationGlobal; - const isDev = Boolean((globalThis as { __DEV__?: boolean }).__DEV__); return isWeb && isDev && !runtime.__PASEO_SCROLL_JANK_INVESTIGATION_DISABLED__; } diff --git a/packages/app/src/utils/test-daemon-connection.ts b/packages/app/src/utils/test-daemon-connection.ts index 997be2b94..8d321856d 100644 --- a/packages/app/src/utils/test-daemon-connection.ts +++ b/packages/app/src/utils/test-daemon-connection.ts @@ -8,6 +8,7 @@ import { buildLocalDaemonTransportUrl, createDesktopLocalDaemonTransportFactory, } from "@/desktop/daemon/desktop-daemon-transport"; +import { isDev } from "@/constants/platform"; function normalizeNonEmptyString(value: unknown): string | null { if (typeof value !== "string") return null; @@ -57,6 +58,7 @@ export async function buildClientConfig( appVersion: resolveAppVersion() ?? undefined, suppressSendErrors: true, reconnect: { enabled: false }, + ...(isDev ? { runtimeMetricsIntervalMs: 10_000 } : {}), ...(connection.type === "directSocket" || connection.type === "directPipe" ? localTransportFactory ? { transportFactory: localTransportFactory }