# Files and folders

> Every file zidane reads or writes, where it lives on macOS and Linux, and the variables that move it.

zidane keeps your sign-ins, settings and sessions in a few folders in your home directory. The terminal app, the desktop app, `zidane run`, the daemon and the ACP adapter all use them, so they share sessions and sign-ins.

## Base folders

zidane uses four folders. On macOS and Windows, all four are `~/.zidane`. On Linux, they follow the XDG convention.

| Folder | Holds | macOS, Windows | Linux |
| - | - | - | - |
| Config | Sign-ins, keybindings, saved hosts, the safelist | `~/.zidane` | `~/.config/zidane` |
| Data | Sessions | `~/.zidane` | `~/.local/share/zidane` |
| State | Settings, logs, the daemon socket | `~/.zidane` | `~/.local/state/zidane` |
| Cache | Large tool results, task logs, the update cache | `~/.zidane` | `~/.cache/zidane` |

zidane picks the layout in this order:

1. `ZIDANE_STORAGE_DIR` is set: all four folders are `$ZIDANE_STORAGE_DIR/.zidane`.
2. `~/.zidane` already holds data: all four stay there, on Linux too, so an upgrade never moves your files.
3. You are on Linux, or set any `XDG_*_HOME` or `ZIDANE_*_DIR` variable: the split layout above. `XDG_CONFIG_HOME` and the other XDG variables move each folder.
4. Otherwise: `~/.zidane`.

For step 2, a `~/.zidane` that holds only files you wrote (`skills/`, `extensions/`, `mcps.json`, `SYSTEM.md`, `AGENTS.md`) does not count.

## Config and data files

| File | Folder | Holds |
| - | - | - |
| `credentials.json` | Config | Provider API keys and sign-ins ([several per provider](https://zidane.si/docs/providers.md#sign-in-and-credentials)), and tokens for saved hosts (`hosts:<id>`) |
| `mcp-credentials.json` | Config | MCP sign-in tokens, mode `0600` |
| `keybindings.json` | Config | Your key overrides ([terminal](https://zidane.si/docs/tui-keys.md), [desktop](https://zidane.si/docs/desktop-keyboard.md)) |
| `hosts.json` | Config | Saved zidane-servers |
| `environment-credentials.json` | Config | Secret options of [session environments](https://zidane.si/docs/sessions.md), mode `0600` |
| `worktrees/` | Config | Git worktrees that worktree sessions create, by default |
| `github-state.json` | Config | The GitHub API limits that zidane saw, shared by the apps and the daemon |
| `projects.json` | Config | The [safelist](https://zidane.si/docs/approvals.md#safelist) of each project |
| `config.json` | Config | `projectDb`: store sessions per [project](#project-folders) |
| `state.json` | State | Settings, last provider, model and agent |
| `logs/<time>.txt` | State | The terminal app's log, when File logging is on |
| `daemon/daemon.sock` | State | The [daemon](https://zidane.si/docs/daemon.md#lifecycle) socket |
| `sessions.db` | Data | Every session (SQLite) |
| `acp-sessions/` | Data | Sessions started through [ACP](https://zidane.si/docs/acp.md) |
| `sessions/<id>/` | Cache | Large tool results saved to disk, background task logs, MCP warnings |

You can delete the cache. The library alone does not use these folders. Its OAuth providers read the file in `ZIDANE_CREDENTIALS_PATH` ([below](#environment-variables)).

## Files you write

zidane reads the files you write from four places, the project first:

| Place | Scope |
| - | - |
| `<project>/.agents/` | This project, any agent |
| `<project>/.zidane/` | This project, zidane only |
| `~/.agents/` | You, any agent |
| `~/.zidane/` | You, zidane only |

`<project>` is the git root above your working folder, or the folder itself outside git. User files stay in `~/.zidane` and `~/.agents` on Linux too.

| Inside | Is | Page |
| - | - | - |
| `skills/<name>/SKILL.md` | A skill | [Skills](https://zidane.si/docs/skills.md) |
| `mcps.json` | MCP servers | [MCP](https://zidane.si/docs/mcp.md) |
| `extensions/<name>/` | An extension | [Extensions](https://zidane.si/docs/extensions.md) |
| `plugins/<name>/` | An Agent Plugin | [Extensions](https://zidane.si/docs/extensions.md#agent-plugins) |
| `commands/*.md` | A `/` command | [Commands](https://zidane.si/docs/extensions.md#commands) |
| `agents/*.md` | A subagent | [Sub-agents](https://zidane.si/docs/sub-agents.md) |
| `AGENTS.md`, `SYSTEM.md` | Instructions | [Rule files](#rule-files) |

## Project folders

A project's `.zidane/` folder holds the project files above, and can hold the project's own sessions:

| Setting | Effect |
| - | - |
| `"projectDb": true` in `config.json`, or `ZIDANE_PROJECT_DB=1` | Inside a git repo, the terminal app keeps `sessions.db` and `state.json` in `<git root>/.zidane/`. Off by default. |

When zidane creates that folder, it adds a `.gitignore` with `*` so git never touches the live database. Every worktree of a repo uses the main checkout's folder. The desktop app always reads the user-level `sessions.db`, so project sessions do not show there.

## Rule files

| File | Effect | Where zidane looks |
| - | - | - |
| `AGENTS.md`, `CLAUDE.md` | Added to the built-in instructions. Every file found loads. | `~/.agents/AGENTS.md`, `~/.zidane/AGENTS.md`, `~/.claude/CLAUDE.md`, then `<project>/AGENTS.md`, `<project>/.agents/AGENTS.md`, `<project>/.zidane/AGENTS.md`, `<project>/CLAUDE.md` |
| `SYSTEM.md` | Replaces the built-in instructions. One file wins. | `<project>/SYSTEM.md`, else `~/.zidane/SYSTEM.md` |
| `.ruler/*.md` | Added like `AGENTS.md`, when "Support Ruler configuration (.ruler)" is on (default) | `.ruler/` in the project and your home |

Files load broadest first, so project files come last and carry the most weight. The User instructions setting (`userInstructionsScope`) limits `AGENTS.md` and `CLAUDE.md` to user files, project files, both (default) or none. `SYSTEM.md` never removes `AGENTS.md` or the environment block (working folder, project root).

## What the desktop app adds

The desktop app keeps its look and layout in the window's local storage, outside `state.json`, so they never reach the terminal app or a server.

| Key | Holds |
| - | - |
| `zg:appearance:v1` | Mode, accent, fonts, motion |
| `zg:layout:v2` | Panel layout per session |

Command palette recents, model picker choices, project icons and editor state live there too.

The sidebar's filters (one set per space) and the space on show are in the app's own database, `zidane-gui.db` in its data folder (`~/Library/Application Support/Zidane` on macOS). Every copy of the app on the computer reads them, an installed one and a development build alike.

## Environment variables

| Variable | Does |
| - | - |
| `ZIDANE_STORAGE_DIR` | Puts all four folders in `<dir>/.zidane` |
| `ZIDANE_PREFIX` | Renames `.zidane` (default `.zidane`) |
| `ZIDANE_CONFIG_DIR`, `ZIDANE_DATA_DIR`, `ZIDANE_STATE_DIR`, `ZIDANE_CACHE_DIR` | Moves one folder, and turns on the split layout |
| `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME` | Standard XDG bases for the split layout |
| `ZIDANE_CREDENTIALS_PATH` | The credentials file the library's OAuth providers and `bun run auth` use (default `~/.credentials.json`). The apps set it to their `credentials.json` at launch, so both read one file. |
| `ZIDANE_GUI_DATA_DIR` | Desktop app only: one folder for everything, to run two installs side by side |
| `ZIDANE_PROJECT_DB` | `1` stores sessions per project, `0` never |
| `ZIDANE_DAEMON_SOCKET` | Another daemon socket path |

zidane-server keeps its own data folder ([server configuration](https://zidane.si/docs/server-config.md)).
