# Setup wizard

> The first screen of a fresh install in both apps, what each step writes, and the same flow in your own React app.

The setup wizard is the first screen of a fresh install, in the terminal app and in the desktop app. It connects a model provider and brings over the setup of another agent. It adds connectors and extensions. It also sets the look, the conversation display, the approval mode and the features. You can change every choice later in Settings.

The preview runs on demo data. Every step works in it, and Start begins a new run.

## The steps

| Step | Asks | Writes |
| - | - | - |
| Welcome | Full setup or Quick start. It also lists what zidane found on this computer. | Nothing |
| Connect | A provider and its sign-in, then the model and the effort. A short test message checks them. | `credentials.json` at sign-in, the model pick at the end |
| Bring your setup | What to copy from Claude Code, and whether to read the Codex and Pi setups where they are | The sessions, `.zidane/*`, `importForeignConfigs` |
| Connectors | Services the agent can use, such as GitHub, Linear and Notion | Your `mcps.json` |
| Skills | Skills from a repository or a pack, with recommended sources to start from | Your skills folder |
| Extensions | Native extensions from the zidane repository | `~/.zidane/extensions/<name>/` |
| Look | The theme. The desktop app also asks for the mode, an accent and the app icon. | The look of the app that runs it |
| Conversation | Focused, Balanced or Detailed, or each transcript setting. Focused also turns off the desktop app's Row icons. The desktop app's list includes Diagrams, and the preview's answer ends on a diagram, so you see the setting at work. | The transcript settings |
| Autonomy | Who approves tool calls, the sandbox, and a spend limit for an API key | `approvalMode`, `sandbox`, `sandboxNetwork`, `maxCostUsd` |
| Features | A short list of switches, each with an example | The switches that changed |
| Ready | A recap, and the imports and installs that run in the background | The records of the run |

The wizard leaves out a step that does not apply. Bring your setup shows only when zidane finds another agent. Connectors, Skills and Extensions show only when installs can run on this computer. Quick start keeps Welcome, Connect, Bring your setup and Ready.

A run writes only what changed. A choice that equals the default writes nothing, so it keeps following future defaults. Imports and installs start when you pass their step, so Back and Skip start nothing.

## When it opens

Each app opens the wizard on the first launch of a fresh install. An install from before the wizard never opens it on its own. When you set up one app first, the other app opens a short run on its first launch: Look, Features and Ready.

| App | Open it again | Turn it off |
| - | - | - |
| Desktop | "Run setup again" at the bottom of Settings, or "Run setup" in the command palette (`cmd+k`) | `ZIDANE_NO_ONBOARDING=1` |
| Terminal | "Run setup again" at the end of Settings › Agent, or "Run setup" in the command palette (`Ctrl`+`Shift`+`P`) | `ZIDANE_NO_ONBOARDING=1`, or `runTui({ onboarding: false })` |

The desktop app opens without a provider. If you send a message with no provider, a "Connect a provider" card shows above the composer. The card opens Connect alone ([desktop app](https://zidane.si/docs/desktop.md#first-launch)). The terminal app needs a provider, so Connect has no Skip there. Its keys are on [terminal app](https://zidane.si/docs/tui.md#first-launch).

## Connectors, skills and extensions

A connector adds an MCP server to your user `mcps.json`. Most connectors sign in through your browser from Ready. The full list is on [MCP](https://zidane.si/docs/mcp.md#connectors).

Connectors and Skills open with a short tutorial: a scene that plays three steps, beside them. The steps play in turn, and a click on a step shows it. `Tutorial` renders the tutorial of a topic, such as `<Tutorial topic="skills" />`.

Skills lists the skills of a repository before you pick any. Type a source, or open a recommended one. Each skill shows its name, its description and its folder, and a pack names the repository each skill comes from. Picks can come from several sources. They install into your user skills folder once you pass the step. The [skills](https://zidane.si/docs/skills.md#add-skills-from-a-repository) page tells how zidane reads a source, and lists the recommended sources.

A native extension installs in one click, from the zidane release that you run. An extension that works through a connector brings it. For example, the Linear extension also adds the Linear connector. The full list is on [extensions](https://zidane.si/docs/extensions.md#native-extensions).

## Autonomy

Each choice of the Autonomy step shows what it gives you and what it prevents. The wizard and Settings show the same two sentences.

| Choice | Gives you | Prevents |
| - | - | - |
| Approvals: Ask | You see each tool call before it runs, and you decide. | Commands and edits that you did not expect. |
| Approvals: Model decision | Long runs that stop only for risky calls. Safe calls run at once. | Risky calls. The decision model blocks them, or asks you when it is not sure. |
| Approvals: Full access | The fastest runs, with no stops at all. | Nothing. Turn on the sandbox, or work in a folder that you can throw away. |
| Sandbox shell commands | More freedom for the agent, with less risk to your computer. | Edits outside the project, and reads of your credentials and keys. |
| Sandbox network | With Allow, commands in the sandbox install packages and fetch pages. | With Deny, no command in the sandbox reaches the internet. |
| Max cost per run | Long runs on an API key, without watching the cost. | A run that costs more than the limit. It stops there. |
| Import configurations from other agents | The MCP servers, skills and commands of your other agents, with no copy to keep in sync. | Off, zidane never runs servers from files that it does not own. |

## Features

The Features step offers these switches. Some apps offer only some of them. Each one shows an example, what it gives you and what it prevents. A feature has one switch, and its parts turn on with it. For example, Browser tab also turns on Agent can use the browser. Settings keeps a switch for each part.

| Feature | Apps | Gives you | Prevents |
| - | - | - | - |
| Codemode | Both apps | Many tool calls in one step. Long tasks take fewer turns, so runs finish faster and cost less. | A context full of small tool results. Only what the script prints goes back to the model. |
| Web search | Both apps | Answers from the web: current docs, error messages, and changes newer than the model. | Off, the agent never reaches a search engine, and works only from your files and what it already knows. |
| Inline autocomplete | Both apps | Press Tab to finish a path, a command or a prompt that you type often. | Typing the same long paths and prompts again and again. |
| Auto-update session titles | Both apps | Session titles that follow what each session is about, so you find it again. | A session list where every title reads the same. |
| Estimate time remaining | Desktop | A countdown on each running session and subagent, so you know when to come back. | Checking a long run again and again to see whether it is done. |
| Spaces | Both apps | Separate session lists, each with its own default model, such as Work and Personal. | Work and personal sessions mixed in one long list. |
| Check for updates | Both apps | A note in the footer when a new version is out. | Running an old version without knowing it. |
| Check usage | Both apps | Your plan usage in the footer, such as the share of your weekly limit. | A surprise stop when you reach your plan limit. |
| Use daemon runtime | Desktop | Runs that keep going after you close the window, and one session open in several windows. | Losing a long run when its window closes. |
| Reminders (also turns on Agent can set reminders) | Both apps | Prompts that run later or on a repeat, and an agent that can come back to a task on its own. | Forgetting to come back to a long task, and checking the same thing by hand every morning. |
| Browser tab (also turns on Agent can use the browser) | Desktop | A browser tab next to the chat. The agent opens pages, clicks and reads them to check its own work. | Switching to another app to check your work, and changes that the agent never saw on screen. |
| Terminals (also turns on Agent can use your terminals) | Desktop | A terminal next to the chat. The agent reads its output, such as an error from your dev server. | Switching to another app to run a command, and commands that the agent types without your approval. |
| Notifications (also turns on Notification sound) | Desktop | A system notification with a short sound when a run finishes or needs your answer. | A run that waits for you while you work in another app or look away. |
| Load project extensions | Both apps | Extensions that a project ships load when you open it, such as its own commands. | Off, code from a repository that you clone never runs on its own. |
| Secrets | Both apps | The agent can ask you for an API key or a token when a task needs one. Its commands use it, and the chat never shows it. | Keys pasted into the chat, where the model, the transcript and the logs keep them. |

## In your app

`zidane-ui/onboarding` shows the wizard in any React app. Your app implements `OnboardingHost`: what the wizard reads, and the actions it asks for. If you leave out a member, the wizard hides its step or its control.

```tsx
import type { OnboardingHost } from 'zidane-ui/onboarding/headless'
import { OnboardingFlow, OnboardingProvider } from 'zidane-ui/onboarding'

export function Setup({ host, onClose }: { host: OnboardingHost, onClose: () => void }) {
  return (
    <OnboardingProvider host={host} onDone={onClose}>
      <OnboardingFlow />
    </OnboardingProvider>
  )
}
```

With `AppHostProvider`, pass the host as `onboarding` and leave `host` off `OnboardingProvider`: it runs on the one in context (`OnboardingHostProvider` does the same without the rest of the app).

| Member | Does | Without it |
| - | - | - |
| `context` | What the run starts from: the app, the mode, what was found, the stored settings, the look. `null` while the app detects | Required |
| `providers.list` | The providers Connect lists, kept current when one turns ready | Required |
| `providers.saveKey` | Stores an API key and a provider's fields | No key form |
| `providers.signIn` | A browser sign-in: its page, device code or question, answered with `submit` | API keys only |
| `providers.test` | Sends one tiny prompt to check the provider answers | No live test |
| `providers.models` | The models Connect offers as the default | No model pick |
| `imports` | What an import from Claude Code brings over, and the import | No Bring your setup step |
| `connectors` | Installed connectors, adding one, its sign-in and the gh login | No Connectors step |
| `skills` | Installed skills, browsing a source, installing picks | No Skills step |
| `extensions` | Installed native extensions, installing one | No Extensions step |
| `themes`, `appIcons` | The looks Look offers, and its live preview | No Look step, no icon |
| `commit` | Writes what the finished run decided | Required |

| Host | From | Offers |
| - | - | - |
| zidane-server | `createServerOnboardingHost({ client })` (`zidane-ui/adapters`) | The providers from `auth.status`, keys, browser sign-ins (pasting the redirect URL or the code finishes them), the live test, the model pick, connectors, native extensions and the final write (`onboarding.complete`: the settings with their resets, and the wizard's records). Keys, sign-ins and installs need an `admin` [token](https://zidane.si/docs/server-security.md#scopes): built after the handshake (`await client.ready`), the host follows `client.can('auth.setApiKey')` and leaves them out for a lesser token (`canConfigure` overrides it). Pass `themes` and `appIcons` to offer Look, and `onCommitted` to apply the look and the model pick on your page. What the server's machine holds (`onboarding.detect`: other agents, local model servers), the providers' custom fields and default model (`onboarding.providers`, stored with `auth.configure`), and, on a server that takes installs, the Claude Code import (`claudeImport.preview` for the step's lists, `claudeImport.run` when the run is committed) and the Skills step (`skills.browse`, `catalog.install`). Pass `oauthCallbackUrl` (the server's `SERVER_OAUTH_CALLBACK_PATH` at your page's origin) to offer a connector's sign-in: the server holds the redirect and finishes it |
| Desktop app | Its IPC host (`gui/src/renderer/src/hosts/electron-onboarding-host.ts`), one per run | Every member but skill pictures |
| In memory | `createFixtureOnboardingHost` (`zidane-ui/onboarding/testing`) | Every member, for demos and tests |

```tsx
import { createServerClient, createServerOnboardingHost } from 'zidane-ui/adapters'

const client = createServerClient({ url: 'wss://agent.example.com', token: 'zds_…' })
const onboarding = createServerOnboardingHost({ client, mode: 'connect' })
```

Your own host's tests run the shared suite: `describeOnboardingHostContract` from `zidane-ui/onboarding/testing/contract` (vitest). It hands your harness a backend to build the host over, and checks the members you list (the others must be undefined).

```ts
import { describeOnboardingHostContract } from 'zidane-ui/onboarding/testing/contract'

describeOnboardingHostContract('my host', backend => ({ host: makeHost(backend) }), ['providers.saveKey', 'providers.test'])
```

For a demo or a test, `createFixtureOnboardingHost` answers every member from demo data:

```ts
import { createFixtureOnboardingHost } from 'zidane-ui/onboarding/testing'

const host = createFixtureOnboardingHost({ delayMs: 0, onCommit: result => console.log(result.settings) })
```

To replace a step, pass your component in the `steps` prop of `OnboardingFlow`. To run the wizard without React, use `createOnboardingRun` from `zidane/chat/pure`. The terminal app runs on it.

### Parts for your own pages

The wizard's parts also work outside it. The desktop app uses them in its Settings.

| Part | Does |
| - | - |
| `Tutorial` | How a part of zidane works: the scene of a `topic` beside its three steps, then your `actions`. The topics are `connectors`, `skills`, `mcp`, `instructions`, `extensions`, `environments`, `files`, `accounts` and `hosts`. |
| `HowItWorks` | A tutorial of your own: a scene beside numbered `steps`. An `illustration` that is a function of the step plays the steps in turn. Reduced motion holds each step until a click. |
| `SkillSourceBrowser` | Lists the skills of a source, and picks them. `compact` shows the recommended sources as chips and leaves out the preview images. |
| `ConversationPreview` | The sample conversation, drawn with a set of transcript settings |
| `ConversationPresetPreview` | The sample conversation with a tab for your settings and one for each preset. A tab only previews. Its Use button calls `onApply`. |
| `ConnectProviderCard` | Says no provider can answer yet, and its Connect button calls `onConnect`: open the wizard in `connect` mode. The desktop app shows it above the composer after such a send. It needs no `OnboardingProvider`. |

```tsx
import { ConversationPresetPreview, Tutorial } from 'zidane-ui/onboarding'

<Tutorial topic="extensions" actions={<button type="button">Build an extension</button>} />
<ConversationPresetPreview settings={settings} onApply={id => applyPreset(id)} />
```

| Entry point | Holds |
| - | - |
| [`zidane/chat/pure`](https://zidane.si/docs/reference/chat-pure.md) | The model: the steps, the reducer, the run, the catalogs, the launch gate and what a run writes |
| [`zidane-ui/onboarding`](https://zidane.si/docs/reference/ui-onboarding.md) | `OnboardingProvider`, `OnboardingHostProvider`, `OnboardingFlow`, the steps, `ConnectProviderCard` and the hooks |
| [`zidane-ui/onboarding/headless`](https://zidane.si/docs/reference/ui-onboarding-headless.md) | `OnboardingHost`, `createOnboardingController` and the labels |
| [`zidane-ui/onboarding/testing`](https://zidane.si/docs/reference/ui-onboarding-testing.md) | `createFixtureOnboardingHost` and its demo data |
| `zidane-ui/onboarding/testing/contract` | `describeOnboardingHostContract`, the shared host suite |
