The manifest: vibe.toml
01vibe.toml is the one file you write to describe a project or a package: its name, what it depends on, where packages come from, and what it delivers. This page lists every table and field with its meaning.
One file, three roles
02Every node, whether a consumer project, a publishable package or a workspace root, has a file named vibe.toml. The tables present decide the role: [project] marks a consumer that is never published, [package] a publishable package, [workspace] a coordinator of members; the first two exclude each other, the third composes with either or with neither.
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.)
05Unknown keys are rejected, not ignored: a manifest written for a newer vibe than the one reading it fails to parse with the offending key named.
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]
| Field | Meaning |
|---|---|
name |
the package name, kebab-case, unique within its group |
group |
the publisher's namespace, a reversed domain such as org.vibevm.world; mandatory; (group, name) is the identity |
kind |
one of the eight kinds; metadata, not identity |
version |
semantic version of this package |
epoch, format |
the package's manifest epoch and its content form (simple by default, normal for the contract-and-source layout) |
authors, license, description, homepage, keywords |
the card every registry shows |
title, abstract |
the human-readable name and the four-question summary shown on documentation shelves; required for doc packages, optional otherwise |
authorship |
who wrote the prose of a doc package: human, ai or mixed; a reader's filter, not the commits' attribution |
describes |
the Package URL of an upstream library this package documents or wraps, for version-matched discovery |
publish |
the publishing posture of a workspace member |
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] carries the same descriptive fields for a consumer, without a version line or a kind.
[requires] and its neighbours
| Table | Meaning |
|---|---|
[requires.packages] |
one key per required coordinate, the value a constraint string or an inline table with version, a git or path source, link for the boot inclusion type, and the visibility marks access, friend and exclude |
[visibility] |
friends, unfriend, allow-friends and ignore-concept-warnings for the package as a whole; see Dependency visibility |
[override] (table) |
rewrites the visibility marks of edges you do not own, keyed "a -> b", or a provider's allow-friends, keyed by its coordinate |
[requires] capabilities |
abstract abilities any provider may satisfy, namespace:name@constraint |
[[requires_any]] |
a disjunction: exactly one of one_of must be satisfied |
[provides] capabilities |
the abilities this package offers |
[obsoletes], [conflicts] |
packages this one supersedes, and packages that cannot coexist with it |
[features] |
optional, additive content sets with a default list; features may depend on features |
[compatibility] |
min_vibe_version and 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.
22A feature adds content and never removes or contradicts any; default lists the features active when nothing is said, and --no-default-features omits them. When two packages require one package with different features, the resolver materialises it once with the union. On the command line vibe install <coordinate> --features a,b, --no-default-features and --all-features control activation.
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).
Where packages come from
| Table | Meaning |
|---|---|
[[registry]] |
an ordered list of package sources: name, url (the organisation root), naming, auth, optional index_url and token_env |
[[mirror]] |
an alternative address for one registry or for any, tried by priority and verified by fingerprint |
[[override]] |
a replacement source for one coordinate, short-circuiting the registries |
[boot] |
workspace-wide loading settings; today a default link |
[i18n] |
preferred and fallback languages in a project; canonical and available in a package |
[workspace] members |
the member paths of a workspace, globs allowed |
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).
31A localised file sits beside the canonical one with a language tag before the extension, README.ru.md next to README.md. Every package ships the canonical form of every file it lists, and translations only add to it, so a project with no translation in its preferred language installs without an error. vibe install --language ru sets the preference for one run.
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.
What a package delivers
| Table | Meaning | Legal in |
|---|---|---|
[boot_snippet] |
source, the snippet file inside the package, and category for its place in the boot order; optional when and a suggested link |
every kind but doc |
[[skill]] |
name, path, description, optional target agents: a skill an agent may install |
every kind |
[[binary]] |
name and crate: a tool vibe builds on install and runs through vibe bin exec |
code-bearing kinds; not doc |
[[mcp_server]] |
name, binary, args: a server registered into agents |
mcp only |
[hooks] |
pre-install and post-install script base paths |
packages |
[[extension]] |
id, point, handler, optional selector and config: a contribution to the lifecycle |
packages and projects |
[[embedded_source]] |
an immutable external source a package refers to without vendoring it | bridge packages |
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:
38A skill is a manifest section, never a kind of its own. include narrows which files of path are projected into an agent's skill folder, and its absence projects the whole tree. A skill may take its body from a declared [[embedded_source]] and add resources below a references/ folder, under the same include selection and traversal checks.
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:
Documentation and its subjects
| Table | Meaning | Legal in |
|---|---|---|
[[documents]] |
package and a version constraint: a subject this documentation describes; required, repeatable |
doc |
[documentation] |
primary (at most one coordinate) and official (any number): the documentation a package names as its own |
every kind |
[translates] |
package and version of the documentation this translation mirrors |
doc |
[navigation] |
pinned, the document paths listed first, and [[navigation.section]] rows with id and title for the folders of the page tree |
doc |
[media] |
icon, banner, preview: source image files within the card limits |
every kind |
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.
A complete example
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"
group = "org.vibevm.core"
version = "1.0.0"
kind = "doc"
title = "VibeVM Manual"
abstract = "What it covers: what VibeVM is and how it gives a coding agent the right text to read; installing vibe; creating a project; packages, registries, the lock file and the machine store; installing, updating, publishing and working offline; giving an agent the vibevm skill and asking it to do the work; the lifecycle from validate to deploy; a full command, manifest, lock-file and settings reference; writing packages of every kind, including documentation and its translations.\nFor whom: people who run vibe in their projects, people who write packages, and the agents that read on their behalf.\nWhat it assumes known: how to use a terminal and a text editor, what a coding agent is, and what a package manager does for a programming language.\nWhat it leaves out: the normative specifications themselves (this manual quotes them, never restates them), the internals of any one agent product, and the design history of vibe."
description = "The VibeVM manual: install vibe, understand packages and the boot lane, work with an agent, author and publish packages."
authorship = "ai"
authors = ["Oleg Chirukhin"]
[i18n]
canonical = "en"
[[documents]]
package = "org.vibevm.core/vibevm"
version = "^1.0"
[navigation]
pinned = ["start/what-vibevm-is", "start/index"]
[[navigation.section]]
id = "start"
title = "Start"
[[navigation.section]]
id = "model"
title = "Model"
[[navigation.section]]
id = "howto"
title = "How to"
[[navigation.section]]
id = "agent"
title = "Agent"
[[navigation.section]]
id = "lifecycle"
title = "Lifecycle"
[[navigation.section]]
id = "authoring"
title = "Authoring"
[[navigation.section]]
id = "reference"
title = "Reference"
[[navigation.section]]
id = "architecture"
title = "Architecture"
[[navigation.section]]
id = "diagnostics"
title = "Diagnostics"
[[navigation.section]]
id = "faq"
title = "Questions"
[[navigation.section]]
id = "glossary"
title = "Glossary"
54The manifest of this manual, generated from the package itself, shows a doc package with a card, a subject and a skill.