(root: Root, permissionMode: PermissionMode, allowDangerouslySkipPermissions: boolean, commands?: Command[], claudeInChrome?: boolean, devChannels?: ChannelEntry[])
| 105 | await gracefulShutdown(0); |
| 106 | } |
| 107 | export async function showSetupScreens(root: Root, permissionMode: PermissionMode, allowDangerouslySkipPermissions: boolean, commands?: Command[], claudeInChrome?: boolean, devChannels?: ChannelEntry[]): Promise<boolean> { |
| 108 | if ("production" === 'test' || isEnvTruthy(false) || process.env.IS_DEMO // Skip onboarding in demo mode |
| 109 | ) { |
| 110 | return false; |
| 111 | } |
| 112 | const config = getGlobalConfig(); |
| 113 | let onboardingShown = false; |
| 114 | if (!config.theme || !config.hasCompletedOnboarding // always show onboarding at least once |
| 115 | ) { |
| 116 | onboardingShown = true; |
| 117 | const { |
| 118 | Onboarding |
| 119 | } = await import('./components/Onboarding.js'); |
| 120 | await showSetupDialog(root, done => <Onboarding onDone={() => { |
| 121 | completeOnboarding(); |
| 122 | void done(); |
| 123 | }} />, { |
| 124 | onChangeAppState |
| 125 | }); |
| 126 | } |
| 127 | |
| 128 | // Always show the trust dialog in interactive sessions, regardless of permission mode. |
| 129 | // The trust dialog is the workspace trust boundary — it warns about untrusted repos |
| 130 | // and checks CLAUDE.md external includes. bypassPermissions mode |
| 131 | // only affects tool execution permissions, not workspace trust. |
| 132 | // Note: non-interactive sessions (CI/CD with -p) never reach showSetupScreens at all. |
| 133 | // Skip permission checks in claubbit |
| 134 | if (!isEnvTruthy(process.env.CLAUBBIT)) { |
| 135 | // Fast-path: skip TrustDialog import+render when CWD is already trusted. |
| 136 | // If it returns true, the TrustDialog would auto-resolve regardless of |
| 137 | // security features, so we can skip the dynamic import and render cycle. |
| 138 | const wasAlreadyTrusted = checkHasTrustDialogAccepted() |
| 139 | if (!wasAlreadyTrusted) { |
| 140 | const { |
| 141 | TrustDialog |
| 142 | } = await import('./components/TrustDialog/TrustDialog.js'); |
| 143 | await showSetupDialog(root, done => <TrustDialog commands={commands} onDone={done} />); |
| 144 | } |
| 145 | |
| 146 | // Signal that trust has been verified for this session. |
| 147 | // GrowthBook checks this to decide whether to include auth headers. |
| 148 | setSessionTrustAccepted(true); |
| 149 | |
| 150 | // Only rebuild GrowthBook if trust transitioned during this startup. |
| 151 | // When the cwd was already trusted, a background init may already be |
| 152 | // running with auth headers; resetting here can race that in-flight |
| 153 | // request and surface a stale init failure even though later refreshes |
| 154 | // succeed. |
| 155 | if (!wasAlreadyTrusted) { |
| 156 | resetGrowthBook(); |
| 157 | void initializeGrowthBook(); |
| 158 | } |
| 159 | |
| 160 | // Now that trust is established, prefetch system context if it wasn't already |
| 161 | void getSystemContext(); |
| 162 | |
| 163 | // If settings are valid, check for any mcp.json servers that need approval |
| 164 | const { |
no test coverage detected