diff --git a/__tests__/e2e/__snapshots__/happy-path.e2e.ts.snap b/__tests__/e2e/__snapshots__/happy-path.e2e.ts.snap
index cbc78e9..413222a 100644
--- a/__tests__/e2e/__snapshots__/happy-path.e2e.ts.snap
+++ b/__tests__/e2e/__snapshots__/happy-path.e2e.ts.snap
@@ -77,7 +77,8 @@ exports[`happy-path flow > navigates Welcome → SystemCheck → Authenticate
warehouse setup, migrations, and onboarding — so it can help ● Sign in to Confidence
without searching the docs. ▶ Set up your agent
○ Connect tools
- ○ Onboard project
+ ◆ Cursor and Codex require full file system access to run ○ Onboard project
+ onboarding.
──────────────────────────────────────────────────────────────────────────────────────────────────
diff --git a/__tests__/e2e/__snapshots__/stale-auth.e2e.ts.snap b/__tests__/e2e/__snapshots__/stale-auth.e2e.ts.snap
index e3e1911..2f64f2e 100644
--- a/__tests__/e2e/__snapshots__/stale-auth.e2e.ts.snap
+++ b/__tests__/e2e/__snapshots__/stale-auth.e2e.ts.snap
@@ -9,7 +9,8 @@ exports[`when auth token is stale > allows re-authentication after expired token
warehouse setup, migrations, and onboarding — so it can help ● Sign in to Confidence
without searching the docs. ▶ Set up your agent
○ Connect tools
- ○ Onboard project
+ ◆ Cursor and Codex require full file system access to run ○ Onboard project
+ onboarding.
──────────────────────────────────────────────────────────────────────────────────────────────────
@@ -31,7 +32,8 @@ exports[`when auth token is stale > allows signing in after failed refresh and p
warehouse setup, migrations, and onboarding — so it can help ● Sign in to Confidence
without searching the docs. ▶ Set up your agent
○ Connect tools
- ○ Onboard project
+ ◆ Cursor and Codex require full file system access to run ○ Onboard project
+ onboarding.
──────────────────────────────────────────────────────────────────────────────────────────────────
@@ -93,7 +95,8 @@ exports[`when auth token is stale > refreshes and authenticates when choosing ex
warehouse setup, migrations, and onboarding — so it can help ● Sign in to Confidence
without searching the docs. ▶ Set up your agent
○ Connect tools
- ○ Onboard project
+ ◆ Cursor and Codex require full file system access to run ○ Onboard project
+ onboarding.
──────────────────────────────────────────────────────────────────────────────────────────────────
diff --git a/__tests__/ui/screens/InstallPluginsScreen.test.tsx b/__tests__/ui/screens/InstallPluginsScreen.test.tsx
index 9a5f5cd..d4387f0 100644
--- a/__tests__/ui/screens/InstallPluginsScreen.test.tsx
+++ b/__tests__/ui/screens/InstallPluginsScreen.test.tsx
@@ -34,6 +34,13 @@ describe('InstallPluginsScreen', () => {
});
});
+ it('shows file system access warning during IDE selection', async () => {
+ using sut = renderScreen(, { screen: ScreenId.InstallPlugins });
+ await waitFor(() => {
+ expect(sut.lastFrame()).toContain('full file system access');
+ });
+ });
+
it('installs plugin and shows success', async () => {
using project = createProjectDir();
using sut = renderScreen(, {
diff --git a/__tests__/ui/screens/OnboardingFlow.test.tsx b/__tests__/ui/screens/OnboardingFlow.test.tsx
index 7050a55..2befd60 100644
--- a/__tests__/ui/screens/OnboardingFlow.test.tsx
+++ b/__tests__/ui/screens/OnboardingFlow.test.tsx
@@ -227,6 +227,55 @@ describe('Onboarding flow', () => {
});
});
+ describe('IDE-specific sandbox warning', () => {
+ it('shows standard warning when IDE is Claude Code', async () => {
+ using project = createProjectDir();
+
+ using sut = renderScreen(, {
+ screen: ScreenId.OnboardProject,
+ dir: project.path,
+ ide: 'claude',
+ goals: ['feature-flags'],
+ });
+
+ await waitFor(() => {
+ const frame = sut.lastFrame()!;
+ expect(frame).toContain('run commands, install packages');
+ expect(frame).not.toContain('entire file system');
+ });
+ });
+
+ it('shows elevated warning when IDE is Cursor', async () => {
+ using project = createProjectDir();
+
+ using sut = renderScreen(, {
+ screen: ScreenId.OnboardProject,
+ dir: project.path,
+ ide: 'cursor',
+ goals: ['feature-flags'],
+ });
+
+ await waitFor(() => {
+ expect(sut.lastFrame()).toContain('entire file system');
+ });
+ });
+
+ it('shows elevated warning when IDE is Codex', async () => {
+ using project = createProjectDir();
+
+ using sut = renderScreen(, {
+ screen: ScreenId.OnboardProject,
+ dir: project.path,
+ ide: 'codex',
+ goals: ['feature-flags'],
+ });
+
+ await waitFor(() => {
+ expect(sut.lastFrame()).toContain('entire file system');
+ });
+ });
+ });
+
describe('selected goal display', () => {
it('shows feature flag steps when goal is feature-flags', async () => {
using project = createProjectDir();
diff --git a/src/ui/tui/screens/install-plugins/components/MainContent.tsx b/src/ui/tui/screens/install-plugins/components/MainContent.tsx
index 599cee8..474f95a 100644
--- a/src/ui/tui/screens/install-plugins/components/MainContent.tsx
+++ b/src/ui/tui/screens/install-plugins/components/MainContent.tsx
@@ -31,6 +31,14 @@ export function MainContent({ phase, detected, error }: MainContentProps) {
+ {phase === 'choose-ide' && (
+
+
+ {Icons.diamond} Cursor and Codex require full file system access to run onboarding.
+
+
+ )}
+
{phase === 'detecting' && }
{phase === 'already-installed' && (
diff --git a/src/ui/tui/screens/onboard-project/OnboardProjectScreen.tsx b/src/ui/tui/screens/onboard-project/OnboardProjectScreen.tsx
index e8b99ac..9701308 100644
--- a/src/ui/tui/screens/onboard-project/OnboardProjectScreen.tsx
+++ b/src/ui/tui/screens/onboard-project/OnboardProjectScreen.tsx
@@ -81,6 +81,7 @@ export function OnboardProjectScreen() {
statusLines={onboarding.statusLines}
error={onboarding.error}
goals={session.onboardingGoals}
+ ide={session.ide}
showTips={showTips}
tip={tip}
/>
diff --git a/src/ui/tui/screens/onboard-project/components/OnboardingLeftPanel.tsx b/src/ui/tui/screens/onboard-project/components/OnboardingLeftPanel.tsx
index dbd76a0..70369a1 100644
--- a/src/ui/tui/screens/onboard-project/components/OnboardingLeftPanel.tsx
+++ b/src/ui/tui/screens/onboard-project/components/OnboardingLeftPanel.tsx
@@ -3,21 +3,19 @@ import { Spinner } from '@inkjs/ui';
import { Colors, Emoji, Icons } from '../../../styles.js';
import { StatusFeed } from '../../../components/StatusFeed.js';
import { TipCard } from '../../../components/TipCard.js';
-import type { OnboardingGoal } from '@shared-kernel/types.js';
+import type { IdeId, OnboardingGoal } from '@shared-kernel/types.js';
import type { OnboardingPhase } from '../useOnboardingProcess.js';
import type { StatusLine } from '../../../lib/status-line.js';
import type { Tip } from '../../../lib/tips.js';
export const MAX_VISIBLE_STATUS = 3;
-const SANDBOX_WARNING =
- 'The AI agent will be able to run commands, install packages, and modify files in your project.';
-
type OnboardingLeftPanelProps = {
phase: OnboardingPhase;
statusLines: StatusLine[];
error: string | null;
goals: OnboardingGoal[];
+ ide: IdeId | null;
showTips: boolean;
tip: Tip;
};
@@ -27,6 +25,7 @@ export function OnboardingLeftPanel({
statusLines,
error,
goals,
+ ide,
showTips,
tip,
}: OnboardingLeftPanelProps) {
@@ -50,7 +49,7 @@ export function OnboardingLeftPanel({
- {Icons.diamond} {SANDBOX_WARNING}
+ {Icons.diamond} {sandboxWarning(ide)}
>
@@ -97,3 +96,14 @@ const GOAL_STEPS: Record = {
function onboardingSteps(goals: OnboardingGoal[]): string[] {
return ['add the Confidence SDK', ...goals.flatMap((g) => GOAL_STEPS[g])];
}
+
+const WARNING_MSG = {
+ sandbox:
+ 'The AI agent will be able to run commands, install packages, and modify files in your project.',
+ relaxed:
+ 'The AI agent will have access to your entire file system as well as run commands and install packages in your project.',
+} as const;
+
+function sandboxWarning(ide: IdeId | null): string {
+ return ide === 'claude' ? WARNING_MSG.sandbox : WARNING_MSG.relaxed;
+}