Skip to content
Open
4 changes: 3 additions & 1 deletion .claude/skills/wizard-architecture/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,12 @@ Each init hook follows the same shape:

The parent hook consumes it as `const initial = useInitial*()` and initializes its own state: `useState<Phase>(initial.phase)`.

**Async variant.** When resolution requires async work (e.g. shelling out to a CLI), seed `useState` with a pending phase and run the async operation in a `useEffect` named `resolveInitial*`. The parent hook overlays its own phase: `installPhase ?? initial.phase`.

Existing init hooks:

- `useInitialAuth` — resolves persisted credentials, syncs auth state to store
- `useInitialDetection` — resolves installed plugins, syncs to store
- `useInitialDetection` — async; detects installed plugins via CLI, syncs to store
- `useInitialOnboarding` — resolves project emptiness / framework, syncs empty-project flag
- `useInitialMcpDetection` — resolves dry-run phase for MCP detection
- `useInitialSystemCheck` — resolves dry-run checks, syncs check results to store
Expand Down
13 changes: 6 additions & 7 deletions __tests__/e2e/__snapshots__/happy-path.e2e.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ exports[`happy-path flow > navigates Welcome → SystemCheck → Authenticate
exports[`happy-path flow > navigates Welcome → SystemCheck → Authenticate → InstallPlugins → ConnectTools → SelectGoal → OnboardProject → Done > connect-tools 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Connect your AI to Confidence Todo (3/5)
Teach your AI Confidence Todo (3/5)

Give your AI assistant direct access to flags, docs, and ● Check system
integration tools. With it, you'll be able to: ● Sign in to Confidence
integration tools via Confidence MCP. With it, you'll be able to: ● Sign in to Confidence
● Set up your agent
● Ask your agent to create and manage feature flags. ▶ Connect tools
● Search docs and generate code, all from your IDE. ○ Onboard project
Expand Down Expand Up @@ -71,11 +71,11 @@ exports[`happy-path flow > navigates Welcome → SystemCheck → Authenticate
exports[`happy-path flow > navigates Welcome → SystemCheck → Authenticate → InstallPlugins → ConnectTools → SelectGoal → OnboardProject → Done > install-plugins 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Teach your AI Confidence Todo (2/5)
Select agent to set up Todo (2/5)

Plugins give your agent tool Confidence-specific skills flag ● Check system
management, warehouse setup, migrations, onboarding — no more ● Sign in to Confidence
searching docs yourself. ▶ Set up your agent
Your agent will get Confidence skills for flag management, ● Check system
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

Expand All @@ -86,7 +86,6 @@ exports[`happy-path flow > navigates Welcome → SystemCheck → Authenticate
❯ Claude Code
Cursor
Codex
Skip (install manually later)

↑↓ navigate enter confirm vX.Y.Z"
`;
Expand Down
53 changes: 0 additions & 53 deletions __tests__/e2e/__snapshots__/skip-plugins.e2e.ts.snap

This file was deleted.

27 changes: 12 additions & 15 deletions __tests__/e2e/__snapshots__/stale-auth.e2e.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
exports[`when auth token is stale > allows re-authentication after expired token and proceeds normally > auth-re-authenticated 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Teach your AI Confidence Todo (2/5)
Select agent to set up Todo (2/5)

Plugins give your agent tool Confidence-specific skills flag ● Check system
management, warehouse setup, migrations, onboarding — no more ● Sign in to Confidence
searching docs yourself. ▶ Set up your agent
Your agent will get Confidence skills for flag management, ● Check system
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

Expand All @@ -18,19 +18,18 @@ exports[`when auth token is stale > allows re-authentication after expired token
❯ Claude Code
Cursor
Codex
Skip (install manually later)

↑↓ navigate enter confirm vX.Y.Z"
`;

exports[`when auth token is stale > allows signing in after failed refresh and proceeds normally > auth-refresh-failed-then-signed-in 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Teach your AI Confidence Todo (2/5)
Select agent to set up Todo (2/5)

Plugins give your agent tool Confidence-specific skills flag ● Check system
management, warehouse setup, migrations, onboarding — no more ● Sign in to Confidence
searching docs yourself. ▶ Set up your agent
Your agent will get Confidence skills for flag management, ● Check system
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

Expand All @@ -41,7 +40,6 @@ exports[`when auth token is stale > allows signing in after failed refresh and p
❯ Claude Code
Cursor
Codex
Skip (install manually later)

↑↓ navigate enter confirm vX.Y.Z"
`;
Expand Down Expand Up @@ -89,11 +87,11 @@ exports[`when auth token is stale > prompts user to sign in again instead of usi
exports[`when auth token is stale > refreshes and authenticates when choosing existing account > auth-refreshed 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Teach your AI Confidence Todo (2/5)
Select agent to set up Todo (2/5)

Plugins give your agent tool Confidence-specific skills flag ● Check system
management, warehouse setup, migrations, onboarding — no more ● Sign in to Confidence
searching docs yourself. ▶ Set up your agent
Your agent will get Confidence skills for flag management, ● Check system
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

Expand All @@ -104,7 +102,6 @@ exports[`when auth token is stale > refreshes and authenticates when choosing ex
❯ Claude Code
Cursor
Codex
Skip (install manually later)

↑↓ navigate enter confirm vX.Y.Z"
`;
Expand Down
8 changes: 4 additions & 4 deletions __tests__/e2e/__snapshots__/stale-mcp-auth.e2e.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ exports[`when MCP config has expired auth tokens > allows skipping when auth is
exports[`when MCP config has expired auth tokens > shows auth-expired status and reconnects successfully > connect-tools-expired 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Connect your AI to Confidence Todo (3/5)
Teach your AI Confidence Todo (3/5)

Give your AI assistant direct access to flags, docs, and ● Check system
integration tools. With it, you'll be able to: ● Sign in to Confidence
integration tools via Confidence MCP. With it, you'll be able to: ● Sign in to Confidence
● Set up your agent
● Ask your agent to create and manage feature flags. ▶ Connect tools
● Search docs and generate code, all from your IDE. ○ Onboard project
Expand Down Expand Up @@ -57,10 +57,10 @@ exports[`when MCP config has expired auth tokens > shows auth-expired status and
exports[`when MCP config has expired auth tokens > shows auth-expired status and reconnects successfully > connect-tools-reconnected 1`] = `
" Confidence by Spotify https://confidence.spotify.com/

Connect your AI to Confidence Todo (4/5)
Teach your AI Confidence Todo (4/5)

Give your AI assistant direct access to flags, docs, and ● Check system
integration tools. With it, you'll be able to: ● Sign in to Confidence
integration tools via Confidence MCP. With it, you'll be able to: ● Sign in to Confidence
● Set up your agent
● Ask your agent to create and manage feature flags. ● Connect tools
● Search docs and generate code, all from your IDE. ○ Onboard project
Expand Down
20 changes: 20 additions & 0 deletions __tests__/e2e/download-fallback.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
createSession,
navigateToPlugins,
selectIdeAndOnboard,
readInvocation,
} from './testing-framework/index.js';

describe('when CLI plugin install fails', () => {
it('falls back to download and references skills by file path in the prompt', async () => {
using session = createSession({ env: { E2E_PLUGIN_INSTALL_FAIL: '1' } });

await navigateToPlugins(session);
await selectIdeAndOnboard(session, 0);

const invocation = readInvocation(session.cwd);

expect(invocation.prompt).toContain('.claude/skills/analyze-project/SKILL.md');
expect(invocation.prompt).not.toContain('`/analyze-project`');
});
});
4 changes: 2 additions & 2 deletions __tests__/e2e/happy-path.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ describe('happy-path flow', () => {
session.checkpoint();

// InstallPlugins
await session.waitForText('Teach your AI');
await session.waitForText('Select agent to set up');
await session.waitForText('Which CLI agent would you like to use?');
expect(session.snapshot()).toMatchSnapshot('install-plugins');
session.checkpoint();
await session.press('Enter');

// ConnectTools
await session.waitForText('Connect your AI to Confidence');
await session.waitForText('Teach your AI Confidence');
await session.waitForText('Connect Confidence tools?');
expect(session.snapshot()).toMatchSnapshot('connect-tools');
session.checkpoint();
Expand Down
4 changes: 2 additions & 2 deletions __tests__/e2e/onboarding-invocation.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const IDE_CASES = [
expectedArgs: ['--print', '--output-format', 'stream-json', '--verbose'],
expectedPromptSnippets: [
'Confidence SDK',
'.claude/skills/analyze-project/SKILL.md',
'/analyze-project',
'existing codebase',
'mcp__confidence-flags__',
],
Expand All @@ -38,7 +38,7 @@ const IDE_CASES = [
expectedArgs: ['exec', '--json', '--sandbox', 'workspace-write', '-'],
expectedPromptSnippets: [
'Confidence SDK',
'.agents/skills/analyze-project/SKILL.md',
'/analyze-project',
'existing codebase',
'confidence-flags:',
],
Expand Down
67 changes: 0 additions & 67 deletions __tests__/e2e/skip-plugins.e2e.ts

This file was deleted.

5 changes: 5 additions & 0 deletions __tests__/e2e/testing-framework/mocks/binaries/claude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ if (args[0] === 'mcp') {
process.exit(0);
}

if (args[0] === 'plugin') {
if (process.env.E2E_PLUGIN_INSTALL_FAIL) process.exit(1);
process.exit(0);
}

if (args.includes('--append-system-prompt')) {
const idx = args.indexOf('--append-system-prompt');
const prompt = args[idx + 1] || '';
Expand Down
5 changes: 5 additions & 0 deletions __tests__/e2e/testing-framework/mocks/binaries/codex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ if (args[0] === 'mcp') {
process.exit(0);
}

if (args[0] === 'plugin') {
if (process.env.E2E_PLUGIN_INSTALL_FAIL) process.exit(1);
process.exit(0);
}

if (args[0] === 'exec') {
let input = '';
process.stdin.setEncoding('utf-8');
Expand Down
3 changes: 3 additions & 0 deletions __tests__/e2e/testing-framework/mocks/binaries/cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ if (args[0] === 'agent' && args[1] === '--version') {
process.exit(0);
} else if (args[0] === 'agent' && args[1] === 'mcp') {
process.exit(0);
} else if (args[0] === 'agent' && args[1] === 'plugin') {
if (process.env.E2E_PLUGIN_INSTALL_FAIL) process.exit(1);
process.exit(0);
} else if (args[0] === 'agent' && args.includes('--print')) {
fs.writeFileSync(
path.join(process.cwd(), '.e2e-onboarding-invocation'),
Expand Down
4 changes: 2 additions & 2 deletions __tests__/e2e/testing-framework/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ export async function navigateToPlugins(session: TerminalSession): Promise<void>
*/
export async function navigateToConnectTools(session: TerminalSession): Promise<void> {
await navigateToPlugins(session);
await session.waitForText('Skip (install manually later)');
session.checkpoint();
await session.press('Enter');
await session.waitForText('Connect Confidence tools?');
await session.waitForText('Plugin installed successfully');
await session.waitForText('Teach your AI Confidence');
}

/**
Expand Down
Loading