Манифест: vibe.toml
01vibe.toml — единственный файл, который вы пишете, чтобы описать проект или пакет: его имя, от чего он зависит, откуда берутся пакеты и что он доставляет. Эта страница перечисляет каждую таблицу и поле с их смыслом.
Один файл, три роли
02У каждого узла, будь то проект-потребитель, публикуемый пакет или корень рабочего пространства, есть файл с именем vibe.toml. Присутствующие таблицы решают роль: [project] помечает потребителя, который никогда не публикуется, [package] — публикуемый пакет, [workspace] — координатора участников; первые две исключают друг друга, третья сочетается с любой из них или ни с одной.
03 Decision.vibe-package.tomlis retired as a distinct filename. Every node — project root, workspace member, published package — carries a singlevibe.toml; the role is expressed by which sections are present. This is the cargo model: oneCargo.tomlcarries[package]and/or[workspace].
04[package]and[project]are mutually exclusive in one file — a node is either a publishable package or a plain project, not both. (Decision 7-α from the design session: keep the two sections distinct rather than folding[project]into a[package]with optionalkind. Explicitness wins;kindstays strictly mandatory wherever[package]appears.)
05Неизвестные ключи отвергаются, а не игнорируются: манифест, написанный для более нового vibe, чем тот, что его читает, не разбирается, и ошибка называет виновный ключ.
06
deny_unknown_fields everywhere — vibevm never silently drops unfamiliar manifest keys; we'd rather fail loud and add the section to the schema than corrupt provenance.
[package]
| Поле | Смысл |
|---|---|
name |
имя пакета, kebab-case, уникальное внутри группы |
group |
пространство имён издателя, перевёрнутый домен вроде org.vibevm.world; обязательно; (group, name) — идентичность |
kind |
один из восьми видов; метаданные, а не идентичность |
version |
семантическая версия этого пакета |
epoch, format |
эпоха манифеста пакета и форма его содержимого (simple по умолчанию, normal для раскладки из contract и source) |
authors, license, description, homepage, keywords |
карточка, которую показывает каждый реестр |
title, abstract |
человекочитаемое имя и сводка из четырёх вопросов, показываемые на полках документации; обязательны для пакетов doc, иначе необязательны |
authorship |
кто написал прозу пакета doc: human, ai или mixed; фильтр читателя, а не атрибуция коммитов |
describes |
Package URL исходной библиотеки, которую этот пакет документирует или оборачивает, для поиска по совпадению версий |
publish |
позиция участника рабочего пространства при публикации |
08 Decision.[package]gains a mandatorygroupfield:
09 Grammar (owner ruling 2026-08-13 — «настоящие домены»): dot-separated segments, each an LDH hostname label —[a-z0-9-]+, ASCII lowercase, hyphen never at a label edge;_is forbidden (it is not legal in a domain). Interior doubled hyphens stay legal, as DNS itself allows (xn--…punycode). A group is therefore grammatically a valid reversed FQDN even though semantically it is a claim, not a credential (§2.10). Enforced byGroup::parse. Considered and rejected: keeping_(groups would not even be formally domains, and the flat<group>.<name>carrier §2.5 would lose its unambiguous split); recording "FQDN-like, not FQDN-valid" as a deliberate looseness (the ruling chose real domain rules). Revisit: a real-world group needing_appears — it cannot, if groups track domains.
10 The package manifest gains card fields; for kinddoctitleandabstractare REQUIRED, for the other kinds optional, and[media]is optional for all:
11 Adocpackage MAY declareauthorshipin[package]:human,aiormixed— who wrote the prose the package carries. It is metadata of the document, kept for the reader who filters a shelf by it; it is never an attribution of the commits or of the repository, whose authorship law isspec://org.vibevm.core/vibevm/common/PROP-000#commits. Absent means unknown: the site shows no badge and a filter by authorship leaves the package out of both named groups.
12[project] несёт те же описательные поля для потребителя, без строки версии и без вида.
[requires] и его соседи
| Таблица | Смысл |
|---|---|
[requires.packages] |
по ключу на требуемую координату; значение — строка ограничения или инлайновая таблица с version, источником git или path, link для типа включения в старт и метками видимости access, friend и exclude |
[visibility] |
friends, unfriend, allow-friends и ignore-concept-warnings для пакета в целом; см. Видимость зависимостей |
[override] (таблица) |
переписывает метки видимости на рёбрах, которыми вы не владеете, ключом "a -> b", или allow-friends провайдера, ключом по его координате |
[requires] capabilities |
абстрактные умения, которые может удовлетворить любой провайдер, namespace:name@constraint |
[[requires_any]] |
дизъюнкция: ровно одно из one_of должно быть удовлетворено |
[provides] capabilities |
умения, которые предлагает этот пакет |
[obsoletes], [conflicts] |
пакеты, которые этот вытесняет, и пакеты, которые не могут сосуществовать с ним |
[features] |
необязательные, аддитивные наборы содержимого со списком default; фичи могут зависеть от фич |
[compatibility] |
min_vibe_version и requires_kinds |
14[requires.packages]inline-table entries accept an optionallinkfield (§2.4):"static" | "dynamic", defaultdynamic. Valid on registry-, path-, and git-source dependencies.
15 Decision. A package'svibe-package.tomlgains a[features]table describing optional, conditionally-activated components:
16
[requires].packages = ["kind:name@<constraint>", …] — concrete pkgref requirements.
17
[requires].capabilities = ["<namespace>:<name>[@<constraint>]", …] — satisfied by any package that provides that capability.
18
[[requires_any]] one_of = [ pkgrefs… ] — disjunction; exactly one must be satisfied. Repeatable table for multiple independent disjunctions.
19
[provides].capabilities = ["<namespace>:<name>[@<semver>]", …] — abstract capabilities the package advertises.
20
[obsoletes].packages = [ pkgrefs… ] — the package supersedes these; the solver flags them for removal on upgrade.
21
[conflicts].packages = [ pkgrefs… ] — mutually exclusive installs.
22Фича добавляет содержимое и никогда ничего не убирает и не противоречит; default перечисляет фичи, активные, когда ничего не сказано, а --no-default-features их опускает. Когда два пакета требуют один пакет с разными фичами, резолвер материализует его один раз с объединением. В командной строке активацией управляют vibe install <coordinate> --features a,b, --no-default-features и --all-features.
23
Additive only. Enabling a feature can introduce additional content; never remove or contradict existing content. (Cargo enforces this informally; vibevm enforces it via vibe check since spec content collisions are easier to detect than code-level ones.)
24 Default features.default = [...]lists features active when no override is given.--no-default-featureson the install / update CLI omits them.
25 Feature unification across the dep graph. Ifpkg-Aandpkg-Bboth depend onpkg-Cand request different features, the solver unifies —pkg-Cis built/materialised once with the union of requested features.
26
vibe install <pkgref> [--features <a,b,c>] [--no-default-features] [--all-features] — control feature activation (cargo-shape).
Откуда берутся пакеты
| Таблица | Смысл |
|---|---|
[[registry]] |
упорядоченный список источников пакетов: name, url (корень организации), naming, auth, необязательные index_url и token_env |
[[mirror]] |
альтернативный адрес для одного реестра или для любого, пробуется по priority и проверяется по отпечатку |
[[override]] |
замена источника для одной координаты, в обход реестров |
[boot] |
настройки загрузки для всего рабочего пространства; сегодня link по умолчанию |
[i18n] |
языки preferred и fallback в проекте; canonical и available в пакете |
[workspace] members |
пути участников рабочего пространства, глобы разрешены |
28
Decision. vibe.toml carries an array of registries:
29 Decision.[[mirror]]entries are parallel alternative URLs for a specific registry (or*for any). During fetch:
30 Decision. Adopt a sidecar file naming pattern with BCP-47 language tags as suffixes, plus first-class language-preference declarations at three levels (CLI flag, project manifest, package manifest).
31Локализованный файл лежит рядом с каноническим, с тегом языка перед расширением, README.ru.md рядом с README.md. Каждый пакет поставляет каноническую форму каждого файла, который перечисляет, а переводы только добавляют к ней, так что проект без перевода на предпочитаемый язык ставится без ошибки. vibe install --language ru задаёт предпочтение на один запуск.
32 A localised file is the canonical filename with a.<lang>segment inserted before the extension.<lang>is a BCP-47 language tag —en,ru,ja,zh-Hans,pt-BR. We also accept short ISO-639-1 codes alone (ru,ja) as a convenience; they map to the BCP-47 tag with no region.
33
Critical invariant: every package must ship the canonical form of every file it lists in [content].files_written. Translations are additive. This is what makes step 3 always reachable; it also lets a project install a package that has zero translation coverage for the user's preferred language without seeing errors.
34
CLI flag: vibe install flow:wal --language ru overrides everything else for this invocation.
Что доставляет пакет
| Таблица | Смысл | Где законна |
|---|---|---|
[boot_snippet] |
source, файл фрагмента внутри пакета, и category для его места в порядке старта; необязательные when и предлагаемый link |
все виды, кроме doc |
[[skill]] |
name, path, description, необязательные целевые agents: навык, который агент может установить |
все виды |
[[binary]] |
name и crate: инструмент, который vibe собирает при установке и запускает через vibe bin exec |
виды с кодом; не doc |
[[mcp_server]] |
name, binary, args: сервер, регистрируемый у агентов |
только mcp |
[hooks] |
базовые пути скриптов pre-install и post-install |
пакеты |
[[extension]] |
id, point, handler, необязательные селектор и config: вклад в жизненный цикл |
пакеты и проекты |
[[embedded_source]] |
неизменяемый внешний источник, на который пакет ссылается, не вендоря его | пакеты-мосты |
36[boot_snippet](package-role) drops thefilenamefield (theNN-target name) and gainscategory(§2.5);source— the path to the boot file inside the package — is retained. It may carry an optional suggestedlinkdefault, and an optionalwhenactivation condition — the declaration site for §2.3's dynamic-entrywhen, closing the gap Phase 4 flagged. For v1 the onlywhenis an operating-system match, the wire string"os:<name>"with<name>one ofwindows/macos/linux; a snippet carrying awhenisdynamic(§2.4). The package author owns this declaration: whether a boot snippet is OS-specific is the author's knowledge, not the consumer's.
37 The MVP section is an array-of-tables, matching the manifest's existing[[requires_any]]/[[registry]]/[[mirror]]shape:
38Навык — секция манифеста, а не отдельный вид. include сужает, какие файлы из path проецируются в папку навыков агента, а его отсутствие проецирует всё дерево. Навык может взять своё тело из объявленного [[embedded_source]] и добавить ресурсы под папкой references/, с тем же отбором include и теми же проверками обхода.
39 Decision. A package declares which of its files are skills for agents in a dedicated manifest section — not by introducing a package kind of its own. The kind register (package_ref.rs,VIBEVM-SPEC.md§4.1) stays closed to skills.
40
When present, only matching files are
projected into the agent's skill directory, preserving their relative
structure; when absent or empty, the whole path tree is projected — the
existing §2.6 behaviour, unchanged.
41 A reference-backed bridge MAY select its body from a declared external source, and any skill MAY add authenticated source resources below a dedicated subdirectory:
42sourceandembedded_sourcename a manifest[[embedded_source]]. Absentsourceretains the package-root meaning. Resource targets are portable relative paths belowreferences/; they cannot replace the localSKILL.md, scripts, or another resource. Include selection, case-fold collision checks and no-follow traversal apply before any agent directory is changed.
43
A code-bearing package declares each shipped tool in its vibe.toml:
44 The[[mcp_server]]table (§2.2) is legal only in this kind — the kind IS the taxonomy, enforced byManifest::validate, not advisory.
45 Hooks live in a package-role[hooks]table invibe.toml:
46
A contribution binds a handler to a point. It is declared as an [[extension]] table — in a package manifest (the package ships and offers the behaviour) or in the project manifest (the host adds its own). The shape is one grammar for every family:
Документация и её предметы
| Таблица | Смысл | Где законна |
|---|---|---|
[[documents]] |
package и ограничение version: предмет, который описывает эта документация; обязательно, повторяемо |
doc |
[documentation] |
primary (не больше одной координаты) и official (сколько угодно): документация, которую пакет называет своей |
все виды |
[translates] |
package и version документации, которую зеркалит этот перевод |
doc |
[navigation] |
pinned, пути документов, которые перечисляются первыми, и строки [[navigation.section]] с id и title для папок дерева страниц |
doc |
[media] |
icon, banner, preview: исходные файлы изображений в пределах ограничений карточки |
все виды |
48[[documents]]is REQUIRED in adocpackage, may list several subjects, and itsversionis a semver constraint.
49[documentation]in the subject names coordinates without versions;primarynames at most one package,officialany number.
50
A translation of documentation is a separate package of kind doc:
51
Images are source files in the package tree, in PNG, JPEG or WebP; SVG is forbidden in this wave because it can carry scripts and the local reader serves the images of proprietary packages as they are. vibe check and the publish gate verify existence, format signature, proportions and size — by signature and dimensions, never by file extension. The limits are small on purpose: packages of ordinary kinds are materialised and committed at consumers.
52 A documentation package MAY declare[navigation]:pinned, the document paths the site and the local reader list first, in the order given; and[[navigation.section]], one row per top-level folder of the page tree with the title the navigation shows for it. Pinning changes only where the named pages stand; every other page keeps the manifest's order. A pinned path that names no page is an error ofvibe check.
Полный пример
53# Written by `vibe doc build-site`: the level-0 view of one published version
# (PROP-057 `##LEVEL-ZERO`). It is a render input and never a package.
[package]
name = "vibevm-docs-ru"
group = "org.vibevm.core"
version = "1.0.0"
kind = "doc"
title = "Руководство VibeVM"
abstract = "Что покрывает: что такое VibeVM и как он даёт агенту-кодеру нужный текст для чтения; установку vibe; создание проекта; пакеты, реестры, лок-файл и машинный store; установку, обновление, публикацию и работу без сети; навык vibevm для агента и работу через него; жизненный цикл от проверки до выкладки; полный справочник команд, манифеста, лок-файла и настроек; написание пакетов всех видов, включая документацию и её адаптации.\nДля кого: для тех, кто запускает vibe в своих проектах, для тех, кто пишет пакеты, и для агентов, которые читают за них.\nЧто считает известным: как пользоваться терминалом и текстовым редактором, что такое агент-кодер и что делает менеджер пакетов для языка программирования.\nЧего не покрывает: сами нормативные спецификации (руководство их цитирует, а не пересказывает), внутреннее устройство отдельных агентов и историю проектирования vibe."
description = "Руководство VibeVM по-русски: установить vibe, понять пакеты и стартовую полосу, работать с агентом, писать и публиковать пакеты."
authorship = "ai"
authors = ["Oleg Chirukhin"]
[i18n]
canonical = "ru"
[[documents]]
package = "org.vibevm.core/vibevm"
version = "^1.0"
[translates]
package = "org.vibevm.core/vibevm-docs"
version = "^1.0"
[navigation]
pinned = ["start/what-vibevm-is", "start/index"]
[[navigation.section]]
id = "start"
title = "Старт"
[[navigation.section]]
id = "model"
title = "Модель"
[[navigation.section]]
id = "howto"
title = "Как сделать"
[[navigation.section]]
id = "agent"
title = "Агент"
[[navigation.section]]
id = "lifecycle"
title = "Жизненный цикл"
[[navigation.section]]
id = "authoring"
title = "Авторам"
[[navigation.section]]
id = "reference"
title = "Справочник"
[[navigation.section]]
id = "architecture"
title = "Архитектура"
[[navigation.section]]
id = "diagnostics"
title = "Диагностика"
[[navigation.section]]
id = "faq"
title = "Вопросы"
[[navigation.section]]
id = "glossary"
title = "Глоссарий"
54Манифест этого перевода, сгенерированный из самого пакета, показывает пакет doc с карточкой, предметом и таблицей [translates], которая называет источник.