Studio Notebook

Claude Code Atlas

Trust Dialogs And First Render Handoff

Follow the interactive startup path from onboarding and trust prompts into the first rendered session.

Why this matters

This chapter explains the last startup gate before Claude Code becomes a fully interactive session. Onboarding may run first, then workspace trust is checked, and only after that does the app apply the full environment and continue.

Trust is the boundary: startup can still show dialogs before it, but the workspace should not behave like a fully ready session until that boundary is crossed.

The handoff in main.tsx

main.tsx measures the pause before the interactive session becomes live. It logs startup timing, starts the setup screen flow, waits for it to finish, and then continues only after the trust and onboarding gates have been resolved.

logEvent('tengu_timer', {
  event: 'startup' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
  durationMs: Math.round(process.uptime() * 1000)
});
logForDebugging('[STARTUP] Running showSetupScreens()...');
const setupScreensStart = Date.now();
const onboardingShown = await showSetupScreens(root, permissionMode, allowDangerouslySkipPermissions, commands, enableClaudeInChrome, devChannels);
logForDebugging(`[STARTUP] showSetupScreens() completed in ${Date.now() - setupScreensStart}ms`);

main.tsx records the pause, waits for the setup screens to finish, and only then continues into the interactive session.

What showSetupScreens() does

The setup flow starts with onboarding when needed. That is the general first-run screen, and it is different from the trust prompt. After onboarding, the trust dialog decides whether the current session can safely proceed. Once trust is accepted, the function marks that boundary for the current session, prefetches system context, and only then applies the full environment variables.

const config = getGlobalConfig();
let onboardingShown = false;
if (!config.theme || !config.hasCompletedOnboarding // always show onboarding at least once
) {
  onboardingShown = true;
  const {
    Onboarding
  } = await import('./components/Onboarding.js');
  await showSetupDialog(root, done => <Onboarding onDone={() => {
    completeOnboarding();
    void done();
  }} />, {
    onChangeAppState
  });
}

That first block only decides whether onboarding appears.

if (!isEnvTruthy(process.env.CLAUBBIT)) {
  if (!checkHasTrustDialogAccepted()) {
    const {
      TrustDialog
    } = await import('./components/TrustDialog/TrustDialog.js');
    await showSetupDialog(root, done => <TrustDialog commands={commands} onDone={done} />);
  }

  setSessionTrustAccepted(true);
  resetGrowthBook();
  void initializeGrowthBook();
  void getSystemContext();
}

That second block is the real trust boundary. If trust has not been accepted, the dialog is shown. Once it resolves, the session marks itself trusted and prefetches the system context for the now-trusted workspace.

applyConfigEnvironmentVariables();

Only after that trust boundary does the code apply the full environment.