# Дерево зависимостей на экране {#root}

@status:doc/work @audience:user,author,agent

[p01] `vibe tree` рисует пакеты, которые разрешил проект, деревом, говорит о каждом, как его текст доходит до агента, и объясняет почему. В терминале команда открывает интерактивный экран; в скрипте печатает простое дерево или JSON. Эта страница об этой команде, её экране и о том, как агент может посмотреть на экран без терминала.

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

## Что показывает {#what-it-shows}

[p03] Команда читает закоммиченный [лок-файл](../glossary/index.xml#lock-file), [манифесты](../glossary/index.xml#manifest) и сгенерированные стартовые файлы проекта по `--path` и ничего не пишет: она никогда не трогает дерево, манифест, лок или сгенерированные файлы. Каждый пакет — одна строка, с колонками в фиксированном порядке. Колонка загрузки — полоса, в которую попал [стартовый фрагмент](../glossary/index.xml#boot-snippet) пакета, прочитанная из сгенерированных файлов, а не пересчитанная, так что экран показывает то, что прочитает агент. Пакет, который встречается под несколькими родителями, рисуется под каждым и после первого раза помечается `(*)`, без повторного раскрытия. Строка статуса показывает размер скомпилированной полосы в байтах и строках.

> [p04] `vibe tree` answers
>   that algorithmically: it renders the resolved package tree annotated with the
>   *effective* load type and the flags that explain it, and emits the same data as
>   JSON for downstream tools.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#TREE-ANSWER>

> [p05] It
>   operates on the workspace discovered from `--path` (default `.`), reading the
>   committed `vibe.lock`, the node manifests, and the generated boot artifacts.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#TREE-INPUTS>

> [p06] `vibe tree` is a **read-only** analyzer over the current project. It mutates
>   nothing (REQ: never writes to the tree, manifests, lockfile, or artifacts).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#TREE-READ-ONLY>

> [p07] Each package is one row. Columns, left to right (REQ: this order):
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#ROW-PER-PACKAGE>

> [p08] The `load` value is the lane a package's boot snippet **actually lands in**, read
> from the committed artifacts (REQ):
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#EFFECTIVE-FROM-ARTIFACTS>

> [p09] `vibe tree` renders each package under each parent, marks a re-occurrence with a
>   trailing `(*)` and does not re-expand it, and cycle-guards the walk on the
>   package's qualified `group/name` (REQ).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#DAG-RENDERING>

> [p10] The status line shows the size of the statically-compiled lane: the byte count
>   and line count of `STATIC.md` (REQ).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#STATIC-SIZE-INDICATOR>

## Три вывода {#three-outputs}

[p11] В терминале по умолчанию открывается интерактивный экран. Когда вывод не терминал или с `--plain`, команда печатает статичное дерево. `--json` выдаёт один объект с теми же данными, что отрисовывает экран, валидный по поставляемой схеме, для любого инструмента ниже по конвейеру.

> [p12] **interactive TUI** — the default on a tty (§2.11);
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#OUT-TUI>

> [p13] **plain** — a static ASCII tree when not on a tty, or under `--plain`.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#OUT-PLAIN>

> [p14] **`--json`** — the machine surface (§2.7), the same data a GUI consumes;
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#OUT-JSON>

> [p15] `vibe tree --json` emits one object, the same data model the TUI renders, valid
>   against the shipped schema (REQ: `schema_version = 1`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#JSON-CONTRACT>

[p16] С деревом приходят два предупреждения. Дрейф корней значит, что список корней в лок-файле расходится с манифестом, то есть лок отстал. Устаревшие артефакты значат, что закоммиченные стартовые файлы расходятся со свежим вычислением, то есть проекту нужен `vibe reinstall`.

> [p17] **root-drift** — `vibe.lock` `meta.root_dependencies` disagrees with the root
>   `vibe.toml` `[requires.packages]` (the lock is behind).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#DIAG-ROOT-DRIFT>

> [p18] **stale-artifacts** — the committed lanes disagree with a fresh `EffectiveBoot`
>   recompute (the tree needs `vibe reinstall`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-036#DIAG-STALE-ARTIFACTS>

## Экран {#the-screen}

[p19] У экрана три режима отображения, каждый из них конфигурация одного виджета дерева и ни один не плоский список, и три формы дерева, выбираемые для каждого режима; активный режим выбирается из меню, показывается в строке статуса и запоминается. Главные действия сидят на функциональных клавишах: `F1` открывает поиск везде, `F2` — меню сортировки, `F3` — меню режима, `F4` — экран настроек, `F6` копирует текущий экран, а `Shift+F6` открывает настройки копирования. Подвал перечисляет активные клавиши, а `Shift` записан стрелкой, чтобы подсказки были короче.

> [p20] REQ. `vibe tree` has three display modes, each a Tree-widget (§3.1) configuration
> (§3.2) — none is a flat list:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#THREE-MODES>

> [p21] REQ. The pipeline offers three shapes, selectable per context on the F2 sort menu
> (§7.2), **default = (a)**:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#THREE-SHAPES>

> [p22] REQ. The active mode is chosen from the F3 menu (§7.1) — not a bare cycle key.
> The active mode is shown in the status line and persisted (§9).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#MODE-SELECT-REQ>

> [p23] REQ. Primary actions are on function keys: `F1` Search Everywhere (§7.3), `F2`
> sort menu (§7.2), `F3` mode menu (§7.1), `F4` settings (opens the `vibe prefs`
> settings UI — PROP-041), `F6` copy / `Shift+F6` copy-settings (§10.2). The footer
> lists the active keys with short labels; **`Shift` is written as `↑`** (e.g.
> `Shift+F6` → `↑F6`) to keep hints short.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#F-KEY-SCHEME>

[p24] Внутри дерева стрелки двигают и панорамируют, `Space` сворачивает узел, `Enter` открывает карточку деталей, а `Shift` с горизонтальной стрелкой переключает вкладки в любом месте приложения. Поиск везде работает как в IDE: вкладка «Все», которая ищет по всему, и вкладки по категориям. Меню сортировки зависит от режима. Элементы управления сгруппированы, и `Tab` шагает между группами. Модальные окна складываются стопкой: каждое новое рисуется поверх предыдущего, `Esc` закрывает верхнее, а на базовом экране `Esc` спрашивает перед выходом, потому что сессия могла грузиться долго.

> [p25] REQ. Within a tree: `↑`/`↓` move selection (+ scroll), `←`/`→` pan horizontally,
> `Space` folds/unfolds the selected node, `Enter` opens the detail card (§8).
> `Shift`+`←`/`→` switches **tabs app-wide** — the tree's display tabs (in tabs
> mode) and the Search Everywhere category tabs (§7.3); plain `←`/`→` stay
> tree-pan (which is why tab-switch takes Shift). These direct keys are exempt
> from the F-key scheme (they are navigation, not commands).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#TREE-KEYS-REQ>

> [p26] REQ. `F1` opens the **Search Everywhere** window — the `vibe-actions` Search
> Everywhere engine (PROP-039 §10), in the IntelliJ IDEA idiom: a hybrid **"All"**
> tab that searches everything, plus **per-category tabs** that narrow it
> (`Tab`/`Shift+Tab` cycle; the "All" tab carries a category checkbox filter). Three
> providers ship (PROP-039 §10.4):
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#F1-SEARCH-REQ>

> [p27] REQ. `F2` opens a dialog whose content depends on the active mode:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#F2-SORT-MENU-REQ>

> [p28] REQ. A screen's controls are partitioned into **focus groups** — cohesive
> clusters the user steps between with `Tab` (and `Shift+Tab` backwards). Within a
> group the group's own keys act (arrows move a radio selection, typing edits a
> field, `Enter` activates a button). A screen with more than one focus group
> declares a **Tab Order** — the explicit sequence `Tab` cycles — per screen; a
> single-group screen has no Tab Order (`Tab` is inert there). `Tab` never switches
> display tabs (that is `Shift+←`/`Shift+→`, §5.3) and never activates a control
> (that is `Enter`).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#FOCUS-GROUPS-REQ>

> [p29] REQ. Modals form a **stack**: opening a modal pushes it; it draws over
> everything below (each lower layer still visible as backdrop); input goes only to
> the top modal; `Esc` pops the top modal (returning to the one beneath). A feature
> may push a modal over a modal — e.g. copy-settings (§10.2) → file-path (§10.5) is
> a depth-2 stack. The base screen is the bottom of the stack; `Esc` at the bottom
> triggers quit-confirm (§7.4), it does not pop.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#MODAL-STACK-REQ>

> [p30] REQ. At the base screen, `Esc` opens a confirm dialog ("Really quit?") with
> `Yes`/`No` buttons; `Yes`/`Enter`-on-Yes quits, `No`/`Esc` returns. The
> confirmation exists because loading may be slow and `Esc` is used pervasively in
> modals — an accidental single `Esc` must not discard the session.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#QUIT-CONFIRM-REQ>

[p31] Копирование работает по принципу «что вижу, то и копирую»: каждый экран сериализует то, что показывает, текстом по умолчанию, Markdown или файлом по запросу; экспорт в PNG зарезервирован и говорит об этом. Состояние интерфейса, режим и выбор сортировки, формы и порядка, сохраняется под `~/.vibe/tree/` и восстанавливается при следующем запуске; отсутствующий или сломанный файл откатывает к умолчаниям. Ярус цветов определяется один раз из окружения, и его можно переопределить в настройках.

> [p32] REQ. `F6` copies the current screen straight to the clipboard as text (the
> provider's default format). `Shift+F6` opens the **copy-settings** modal: a
> `RadioGroup` for **format** (Markdown / PNG — and later PlantUML / Mermaid) and a
> `RadioGroup` for **destination** (clipboard / file). Confirming with destination
> = file pushes the file-path modal (§10.5) over it (§6 stack).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#COPY-FLOW-REQ>

> [p33] REQ. Each screen (tree/sub-tables/tabs; the card) supplies a **copy provider** —
> an object that knows how to serialize *what is currently shown* into a copy
> format. A tree provider serializes the tree with its current display options; the
> card provider serializes the card's fields. Copy is "what I see is what I copy":
> in tabs mode only the active tab is serialized.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#COPY-PROVIDERS-REQ>

> [p34] REQ. PNG export (a rasterized tree image; a designed package info-card image) is
> **reserved** — selecting PNG opens the `ComingSoon` modal (§2.10) until the
> rasterization (font + image crates) is built. Named non-goal-for-now (§12).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#PNG-RESERVED>

> [p35] REQ. UI state persists under `~/.vibe/tree/` as one or more JSON files. Saved:
> the active mode (§4.4), the per-context sort + shape + block-order choices (§7.2,
> §3.3). On TUI launch the settings are loaded and the UI restored to them; a
> missing/corrupt file falls back to defaults (never a hard error). Writing is
> atomic; the directory is created if absent. (This is the machine-global
> `~/.vibe/` config root, distinct from the project's `.vibe/`.)
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#SETTINGS-PERSISTENCE>

> [p36] REQ. Tier detection is a **pure function** over the environment —
> `detect_tier(colorterm: Option<&str>, term: Option<&str>) -> Tier` (`$COLORTERM`
> first, then `$TERM`; `crossterm` exposes no colour-count API). The TUI reads the
> env once at launch in a sanctioned spot and feeds the values in; the detected
> tier is overridable through the settings system (§9). **The default is Tier 3**:
> anything not explicitly dumb (an unset or empty `TERM`/`COLORTERM`, or a generic
> `TERM=xterm`) is assumed truecolor, because every incumbent terminal renders
> truecolor and several (notably on Windows) do not advertise the capability via
> env at all — defaulting to Tier 3 keeps a modern terminal colourful instead of
> degrading it to mono. The lower tiers are the **fallback** (the degradation
> path), reached only when the environment explicitly advertises a lower
> capability (a 256-colour `TERM`, or an explicitly dumb `TERM=linux`/`dumb`);
> Tier 0 is never reached from an unset env. A genuinely limited terminal is
> otherwise overridden via `vibe.tree.tier`.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-037#TIER-DETECTION>

## Собственный терминал {#the-terminal-app}

[p37] `vibe term` запускает vibeterm, терминальное приложение с оболочкой внутри, так что экран можно использовать и рассматривать сам по себе. `vibe tree`, запущенный внутри vibeterm, не открывает второго окна: он занимает текущий терминал на время сессии.

> [p38] REQ. `vibe term` launches the **vibeterm** terminal app hosting an interactive
>   shell, so the terminal can be used and eyeball-debugged standalone.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#TERM-LAUNCHER>

> [p39] A `vibe tree` launched
>   **inside** vibeterm (this env present) does not spawn a second window — it
>   upgrades the current terminal in place: the `-t` / vibeterm launch resolves to
>   the in-terminal console TUI here, so a plain shell becomes a "VibeTree terminal"
>   for the session (PROP-036 §2.13). Outside vibeterm, `-t` still opens the desktop
>   app.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#IN-PLACE-UPGRADE>

## Как посмотреть на экран из агента {#for-agents}

[p40] У агента нет терминала, поэтому команды `vibe aiui` отрисовывают экран для него. Глагол render строит ту же модель, что и `vibe tree` по `--path`, прогоняет скрипт клавиш при заданном размере, по умолчанию `80x24`, и печатает снимок в одном из двух форматов: простым текстом или `cells`, кодированием повторов каждой ячейки с её глифом, цветами и модификаторами, для утверждений о стиле. Скрипт клавиш — разделённый пробелами список имён клавиш: функциональные клавиши, стрелки, `Enter`, `Esc`, `Tab` и остальные, с префиксом `Shift+`, где нужно. Клавиши, которые вышли бы из процесса или изменили мир, `F4` и клавиши копирования, отвергаются, а не выполняются. Глагол model проецирует состояние вовсе без отрисовки, а глаголы terminal управляют живой сессией vibeterm.

> [p41] REQ. `vibe aiui` is the agent-facing command family. Its render-plane verb:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#AIUI-FAMILY>

> [p42] builds the `vibe tree` model at `--path` (the same resolver `vibe tree` uses),
>   drives `--send` (§3) at `--size` (default `80x24`), and prints the `--format`
>   snapshot (§2, default `text`) to stdout.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#RENDER-VERB-SEMANTICS>

> [p43] REQ. A rendered Buffer projects to one of two **snapshot formats**, the same
> schema every observation plane emits:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#SNAPSHOT-FORMATS>

> [p44] **`cells`** — JSON: `{cols, rows, rows:[[run,…],…]}` where each **run** is
>   `{n, ch, fg?, bg?, mods?}` — `n` cells of glyph `ch` sharing a style, run-length
>   encoded per row; `fg`/`bg` are `#rrggbb` (or an ANSI role name), `mods` the set
>   of `bold`/`dim`/`italic`/`underlined`/`reversed` present. Enables style/colour
>   assertions (e.g. "the active group's border run is the accent colour").
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#FMT-CELLS>

> [p45] REQ. A **key script** is a space-separated list of key names driving the TUI
>   before the snapshot. The grammar: function keys `F1`–`F12`; navigation `Up`,
>   `Down`, `Left`, `Right`; `Enter`, `Esc`, `Tab`, `BackTab`, `Space`, `Backspace`;
>   a `Shift+` prefix on any of them (e.g. `Shift+Left`, `Shift+Tab` ≡ `BackTab`).
>   Names are case-insensitive.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#KEY-SCRIPT-GRAMMAR>

> [p46] REQ. A scripted key that would **escape the process or mutate the world** is
>   refused, not executed: `F4` (spawns the settings subprocess) and `F6`/`Shift+F6`
>   (write the clipboard) are rejected by the key-script parser (§3).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#SIDE-EFFECT-KEYS-REFUSED>

> [p47] REQ. The **model-plane** verb projects the TUI state — no rendering at all:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#MODEL-VERB>

> [p48] REQ. The **terminal-plane** verbs drive a live vibeterm control session:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-cli/PROP-042#TERMINAL-VERBS>

[p49] Под этим у каждого действия интерфейса есть адрес, `action://<group>/<name>`, а наблюдаемое состояние — один сериализуемый снимок с фокусом, открытыми модальными окнами, видимыми строками и включёнными действиями с их причинами, без типов отрисовки. Безголовая поверхность перечисляет действия, вызывает одно по адресу, возвращает снимок и выполняет поиск; так агент управляет экраном, не видя его.

> [p50] REQ. An action is named by an **`ActionAddr`** with the textual form
> `action://<group>/<name>[?<params>]`, where `<group>` is a dotted namespace (e.g. `vibe.tree`,
> `core`), `<name>` is a dotted/kebab identifier (e.g. `copy.markdown`, `search.everywhere`), and the
> optional `<params>` is a `&`-separated `key=value` query carrying invocation parameters (§5).
> `(group, name)` is the identity; the query is *not* part of identity. Examples:
> `action://vibe.tree/copy.markdown`, `action://vibe.tree/sort?by=name&dir=asc`,
> `action://core/search.everywhere`.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-actions/PROP-039#ADDRESS-GRAMMAR>

> [p51] REQ. The observable UI state is a **serialisable `ModelView`** snapshot (focus, open modals, visible
> rows, current tree/selection, the active tab, the set of enabled actions with their addresses +
> reasons). It is a pure projection of the Model and carries **no rendering types** — so an AI reads
> structured state, never pixels.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-actions/PROP-039#MODEL-VIEW-DEF>

> [p52] REQ (**built**; the in-process form ships). The core offers a **headless AIUI** surface:
> `list_actions(filter?)` (enumerate the registry with live enablement + reasons + params),
> `invoke(addr, args)` (the same `invoke` as §7.1), `state() -> ModelView` (§11.2), and
> `search(query, tab?)` (drive §10 programmatically). `vibe-actions/src/aiui.rs` implements
> `list_actions` + `invoke`, and `vibe aiui state` projects the §11.2 `ModelView` live, citing this
> section in its own `--help`. Because enablement is pure + introspectable, the
> model is serialisable, and invocation is address-based, this surface is a thin adapter with a no-op
> `present`. The architecture must keep it a thin adapter — it was **prototyped on the TUI**, and the
> remaining JSON-RPC / MCP bindings are further adapters over the same surface. This is the founding
> AIUI goal (DO18): the headless surface is the **reference**; visual surfaces are projections.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-actions/PROP-039#AIUI-REFERENCE>

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

[p53] Английский — полная локаль интерфейса и последний запасной вариант; другая локаль может отставать и откатывается молча. Пакет может поставить собственный файл локали, а языковой пакет может его заменить.

> [p54] REQ. English is the **default, mandatory-complete** locale and the terminating fallback. Other locales
> may lag and fall back silently. Locale switch is atomic (`ArcSwap<Catalogue>`); a package may ship
> `locales/<lang>.ftl`, and a dedicated language-pack package may override, merged by explicit priority
> (language-pack > package locale > inline English).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-actions/PROP-039#I18N-FALLBACK-LAW>

