# Настройки, пути и окружение {#root}

@status:doc/work @audience:user

[p01] vibe держит собственные файлы в одной папке в вашей домашней директории и читает несколько переменных окружения. Эта страница перечисляет содержимое папки, каждую переменную и то, что побеждает, когда они расходятся.

[p02] Example `vars` is copied from the source page at projection time.

## Папка: ~/.vibe/ {#the-folder}

[p03]
| Путь | Что держит |
| --- | --- |
| `~/.vibe/cache/` | машинное хранилище скачанных пакетов, по идентичности |
| `~/.vibe/registries/` | git-клоны реестров, используемые для скачивания пакетов |
| `~/.vibe/opt/` | установленные версии vibe, их лаунчеры в `opt/bin/` и скачанная оболочка читалки |
| `~/.vibe/registry.toml` | машинные реестры, зеркала и переопределения, подмешиваемые после проектных |
| `~/.vibe/config.toml` | пользовательская конфигурация: `[env]`, `[install]`, `[net]` |
| `~/.vibe/settings.toml` | ваши предпочтения приложения, первый из трёх слоёв |
| `~/.vibe/<host>.publish.token`, `~/.vibe/git.publish.token` | токены публикации, доступные для чтения только вам; никогда не печатаются, никогда не копируются |
| `~/.vibe/search-cache/` | кэшированные результаты поиска со сроком жизни |

> [p04] **The settings home is `~/.vibe`** (owner, 2026-08-20). This document previously named `~/.config/vibe/config.toml`; the code has treated `~/.vibe` as canonical all along and the XDG path only as a legacy location an operator is invited to migrate out of. The correction is to this document, not to the tree.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#THE-SETTINGS-HOME-IS-DOT-VIBE-NOT-XDG>

> [p05] **Registries keep their own file, and the reason is that one of the two is shareable and the other is not** (owner, 2026-08-20). A team can hand a colleague `registry.toml` — «here is where we get packages from» — without handing over every personal preference in `config.toml`. Merging them would make the shareable thing inseparable from the private one. **This is already how the tree works**, so the decision costs nothing to keep and would cost a migration to undo.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#REGISTRIES-KEEP-THEIR-OWN-FILE>

[p06] На Windows папка — `%USERPROFILE%\.vibe\`. Старое место под `~/.vibevm/` не читается никогда; перенесите всё, что там держали.

## Внутри проекта {#inside-a-project}

[p07]
| Путь | Что держит |
| --- | --- |
| `.vibe/settings.toml` | общие предпочтения команды, закоммичены; второй слой |
| `.vibe/settings.local.toml` | ваша тонкая настройка для одного проекта, игнорируется git; третий слой |
| `.vibe/lifecycle.toml`, `.vibe/trace/`, `.vibe/agentic/` | отпечатки жизненного цикла, трассы компиляции и почтовый ящик эстафеты агента; машинное состояние, не коммитится |

> [p08] **L2 — repo-shared** (`.vibe/settings.toml` inside the repo, **committed**): the team's preferences
>   for this project (analogue: VSCode `.vscode/settings.json`; IntelliJ `.idea/` shared `*.xml`,
>   `RoamingType.DEFAULT`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#L2-REPO-SHARED>

[p09] Предпочтения сливаются слой за слоем: скаляр из более высокого слоя заменяет, таблицы сливаются глубоко, массивы заменяются целиком. `vibe prefs list` показывает каждое разрешённое значение с его происхождением, `vibe prefs show-origins` — [вклад](../glossary/index.xml#contribution) каждого слоя, а `vibe prefs set` пишет один ключ в один слой.

> [p10] **Scalars** (string/number/boolean): **last-wins** (the higher layer's value replaces).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#MERGE-SCALARS>

> [p11] **Arrays**: **replace, not concatenate** — a higher-layer array fully replaces the lower one (the
>   non-obvious VSCode semantics; the dotnet #118204 trap is avoided by making this explicit and
>   documented).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#MERGE-ARRAYS>

[p12] Три слоя: машина, `~/.vibe/settings.toml`, репозиторий, `.vibe/settings.toml`, и ваша собственная копия для одного проекта, `.vibe/settings.local.toml`, которую `vibe init` добавляет в `.gitignore`, чтобы она никогда не закоммитилась случайно. Старшинство между ними — один фиксированный закон, записанный в бинарнике. Отсутствующий или сломанный файл считается отсутствующим с предупреждением, никогда не ошибкой. Каждый ключ объявлен с типом и умолчанием, а неизвестный ключ — громкое предупреждение на старте и в `vibe prefs check`. Эти файлы держат то, как vibe выглядит и ведёт себя для вас; свойства проекта живут в манифесте, а закоммиченный файл настроек не может нести секретов. Команды: `vibe prefs get`, `set` с `--layer`, `list`, `check`, `migrate` и `show-origins`.

> [p13] **L1 — user-machine** (`~/.vibe/`, e.g. `~/.vibe/settings.toml`): this user's global defaults on this
>   machine (analogue: VSCode User settings; IntelliJ Application `options/*.xml`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#L1-USER-MACHINE>

> [p14] **L3 — user-project** (`.vibe/settings.local.toml`, **gitignored**): this user's fine-tuning for
>   this specific project (analogue: IntelliJ `$WORKSPACE_FILE$` = `.idea/workspace.xml`, personal,
>   `RoamingType.DISABLED`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#L3-USER-PROJECT>

> [p15] REQ {#gitignore-autogen} (Δ-06, imperative 6). `vibe init` writes a `.gitignore` entry for
> `.vibe/settings.local.toml` (and the L3 pattern) so a personal file is **never accidentally
> committed** — the IntelliJ `workspace.xml` "keeps popping up" pain (§4.2.3) avoided by default, not
> by user discipline.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#gitignore-autogen>

> [p16] REQ {#precedence-law} (Δ-11, imperative 1). The precedence is a **law**, fixed in one place (this
> section) and encoded in the binary, never ambiguous:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#precedence-law>

> [p17] REQ {#missing-is-default}. A missing or corrupt file falls back to defaults — **never a hard error**
> (analogous to PROP-037 §9). A parse error is reported as a non-fatal diagnostic and the layer is
> treated as absent.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#missing-is-default>

> [p18] REQ {#schema-first} (Δ-04, imperative 4). The preference surface is **schema-first**: every key is
> declared with `type`, `default`, and metadata. Unknown keys (typos, retired names) produce a **loud
> warning at boot and at `vibe prefs check`** — never a silent ignore (the VSCode JSON-schema-gap pain,
> §4.1.5; the IntelliJ un-validated-XML pain).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#schema-first>

> [p19] REQ {#app-prefs-not-project}. The system stores **application/user preferences** — how vibevm's
> surfaces *look and behave for this user* (the TUI's palette/glyph/tier/mode/sort/shape/fold; future
> vibe-app prefs). It does **not** store project properties. `vibe.toml` (the vibe-PROJECT manifest —
> package/deps/build, the `pom.xml` analogue, governed by [PROP-000 §4](../../common/PROP-000.xml) and
> the `Manifest`/`UserConfig` types) is a **separate subsystem** this contract does **not** extend or
> mutate. The split mirrors IntelliJ `.idea/` (IDE settings) vs `pom.xml` (build), and VSCode
> `.vscode/settings.json` (workspace UI) vs `package.json` (project).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#app-prefs-not-project>

> [p20] REQ {#no-secrets-in-committed} (imperative 7; `secrets-hygiene` flow). Preference files are
> **non-secret** (UI look/behaviour). The schema forbids a committed `.vibe/settings.toml` from carrying
> a `[secret]`-style section; `vibe prefs check` refuses such a file (the `.idea`/`.vscode` keystore-leak
> vector, §4.3.3). Secrets belong in `vibe.toml`'s `api_key_env` (env-var name) or a per-user keychain —
> never in app-prefs.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#no-secrets-in-committed>

> [p21] REQ {#prefs-command}. The `vibe prefs` command surface: `vibe prefs get <key>`, `vibe prefs set <key>
> <value> [--layer L1|L2|L3]`, `vibe prefs list`, `vibe prefs check` (validate all layers), `vibe prefs
> migrate`, `vibe prefs show-origins [key]`. (Distinct from `vibe show config`, which remains the
> project-config view.)
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-040#prefs-command>

[p22] `vibe prefs` без аргументов открывает экран настроек в терминале: дерево страниц слева, отрисованное тем же виджетом, что и `vibe tree`, и форма справа. Правка поля пишет в слой, который вы выбираете: по умолчанию ваш собственный проектный слой внутри проекта и машинный слой вне его. Поле по запросу показывает происхождение, побеждающий слой и затенённые, а задать или очистить можно один слой, не трогая остальные. Поиск находит настройки по ключу, имени, описанию и синонимам.

> [p23] REQ {#tree-widget}. The left pane is a **tree of pages** (groups → pages) rendered through the PROP-037
> `Tree` widget (so it inherits its glyphs, theme, fold, keyboard model — no bespoke renderer). `↑`/`↓`
> move, `←`/`→` fold/expand, `Enter` opens the focused page's form (§4) in the right pane.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-041#tree-widget-req>

> [p24] REQ {#tree-context}. The tree respects the active project context (which repo's `.vibe/` is L2); a
> no-project session shows only L1 (user-machine) pages.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-041#tree-context>

> [p25] REQ {#write-layer-choice}. Editing a field writes to a **chosen layer** (default L3 for a project
> session, L1 for a no-project session), selected in the form — never silently to the wrong layer (the
> VSCode `.vscode-overwrites-contributors` pain, §4.1.2). Writing to a layer the key's `scope` forbids is
> refused with the reason (PROP-040 §7).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-041#write-layer-choice>

> [p26] REQ {#provenance-view} (PROP-040 §5, §8). A field shows its **provenance** on demand: the resolved
> value plus each layer's contribution (`default / L1 / L2 / L3 / CLI / env`), the winning `origin`
> (file:line where known), and which layers are shadowed. This is the visual form of `vibe prefs
> show-origins` (PROP-040 §8) — the first-class answer to "which layer is winning?".
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-041#provenance-view>

> [p27] REQ {#provenance-edit}. From the provenance view the user can **override at a specific layer** (set L3
> without touching L2, or clear L3 to fall back to L2) — direct, layer-aware editing, not a single
> mystery write.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-041#provenance-edit>

> [p28] REQ {#settings-search} (Δ-15; the archived settings study §3.7). A search (the `vibe-actions` Search Everywhere
> engine, PROP-039 §10 — the same engine the `vibe tree` TUI uses) finds settings by **key, display name,
> description, and synonyms**. Selecting a result opens the owning page with that field focused. The
> search index is built from the page registry (§2) so a new page is searchable with no extra wiring.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-settings/PROP-041#settings-search>

## Переменные окружения {#variables}

[p29]
| Переменная | Эффект |
| --- | --- |
| `VIBE_SETTINGS` | переносит всю папку `~/.vibe/` по заданному пути, используемому как есть |
| `VIBE_REGISTRY_CACHE` | переносит кэш клонов реестров |
| `VIBE_OFFLINE` | запрещает доступ к сети, как `--offline`; истинные значения `1`, `true`, `yes`, `on` |
| `VIBE_INVOKED_BY` | называет вызывающего агента, как `--invoked-by`; проставляется в каждый JSON-отчёт |
| `VIBE_UNATTENDED` | отвечает на все подтверждения и отказывает мастерам, как `--unattended` |
| `VIBE_NO_DEFAULT_REGISTRY` | игнорирует встроенный реестр vibe, собранного из исходников |
| `VIBEVM_INDEX_URL_<REGISTRY>` | расположение индекса одного реестра; `none` выключает его индекс |
| `VIBEVM_REGISTRY_TOKEN_<HOST>` | токен, который читает реестр с `auth = "token-env"` |
| `VIBEVM_PUBLISH_TOKEN` | токен публикации; побеждает файлы токенов |
| `VIBEVM_HOME`, `VIBEVM_INSTALL_ROOT` | справочно: где живут установленные версии; истина — собственное расположение работающего бинарника, а `vibe vars diff` показывает, где они расходятся |
| `VIBE_LOG` | фильтр журнала процесса |

> [p30] It resolves through the established CLI config layering — flag, then a `VIBE_OFFLINE` environment variable, then a user-config `[net]` key; the flag wins. This mirrors the resolved-posture pattern already used for `--unattended` / `VIBE_UNATTENDED` (`output::resolve_unattended`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#OFFLINE-LAYERING>

> [p31] **The environment variable `VIBEVM_INDEX_URL_<REGISTRY>` is the ladder's top rung — the operator's per-run re-point, no longer the only source.** Until 2026-08-20 it was the sole locator, deliberately weaker than the manifest field it stood in for (per-shell, per-run, travelling with neither project nor lockfile) — which is why it never closed the requirement above. Now it *overrides* the key: env beats `index_url` beats the default, and `none` at either explicit rung disables the index. The name normalization (`ASCII alphanumerics upper-cased, the rest to `_``) is unchanged.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-index/PROP-005#INDEX-URL-TODAY-IS-AN-ENVIRONMENT-VARIABLE>

> [p32] **`token_env` defaulting.** When `auth = "token-env"` and `token_env` is omitted, the env-var name is derived from the registry's host: lowercase host, dots and hyphens to underscores, prefixed with `VIBEVM_REGISTRY_TOKEN_` and uppercased. For `https://gitlab.company.com/vibespecs` the default is `VIBEVM_REGISTRY_TOKEN_GITLAB_COMPANY_COM`. Operators who want stable env-var names across host migrations set `token_env` explicitly; everyone else gets a working default.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#TOKEN-ENV-DEFAULTING>

> [p33] **`$VIBEVM_HOME` / `$VIBEVM_INSTALL_ROOT` (env) → advisory.** Still set
>    durably for external `JAVA_HOME`-style tools, but no longer the source of
>    truth. They may lag (new shells only); `vibe vars` (§2.14) reconciles,
>    and a managed `vibe` whose `current_exe`-derived home disagrees with the
>    env prints a one-line stderr warning at startup (suppressed outside a
>    managed run).
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#LAYER-ENV-ADVISORY>

## Старшинство {#precedence}

[p34] Для одной и той же настройки флаг в командной строке побеждает переменную окружения, та побеждает конфигурацию проекта, та — пользовательскую, та — встроенное умолчание. Тот же порядок для [реестров](../glossary/index.xml#registry): список проекта побеждает список машины.

> [p35] Project-level `[[registry]]` always overrides the user-level default — the same precedence the `UserConfig` `[env]` layer already follows (the project / live value wins).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#PROJECT-OVERRIDES>

## Особые случаи и правила {#edge-cases}

[p36] Файлы токенов — поверхностные секреты: ограничьте их своим пользователем, никогда не коммитьте, никогда никуда не вставляйте их содержимое. vibe затирает токен в каждом выводе и ошибке, и дисциплина с вашей стороны та же.

> [p37] 20. Token secrecy and adapter scope
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#token-secrecy>

> [p38] **Decision.** Publish tokens, registry-API tokens, and any LLM-provider keys handled by vibevm are **surface secrets** in the sense of the `secrets-hygiene` flow (`spec://org.vibevm.world/secrets-hygiene/flows/secrets-hygiene/SECRETS-HYGIENE-PROTOCOL#surface-secret`): their **value** MUST NOT appear on any surface vibevm produces, though their **source** (env-var name, file path) may be printed.
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#TOKEN-SURFACE-SECRET>

[p39] `vibe show config` — вид конфигурации проекта с происхождением каждого значения; `vibe prefs` — файл предпочтений приложения. Это разные файлы и разные команды.

