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 spec: Decision: vibe-package.toml is retired…
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 spec: [package] and [project] are mutually exclusive…
[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 spec: deny_unknown_fields everywhere — vibevm never silently…
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 quote from the specification
Decision.[package]gains a mandatorygroupfield:
09 spec: Grammar (owner ruling 2026-08-13 — «настоящие…
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 spec: The package manifest gains card fields…
The package manifest gains card fields; for kinddoctitleandabstractare REQUIRED, for the other kinds optional, and[media]is optional for all:
11 spec: A doc package MAY declare authorship…
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 spec: [requires.packages] inline-table entries accept an optional…
[requires.packages]inline-table entries accept an optionallinkfield (§2.4):"static" | "dynamic", defaultdynamic. Valid on registry-, path-, and git-source dependencies.
15 spec: Decision: A package's vibe-package.toml gains…
Decision. A package'svibe-package.tomlgains a[features]table describing optional, conditionally-activated components:
16 quote from the specification
[requires].packages = ["kind:name@<constraint>", …] — concrete pkgref requirements.
17 spec: [requires].capabilities = ["<namespace>:<name>[@<constraint>]", …] — satisfied…
[requires].capabilities = ["<namespace>:<name>[@<constraint>]", …] — satisfied by any package that provides that capability.
18 spec: [[requires_any]] one_of = [ pkgrefs… ]…
[[requires_any]] one_of = [ pkgrefs… ] — disjunction; exactly one must be satisfied. Repeatable table for multiple independent disjunctions.
19 quote from the specification
[provides].capabilities = ["<namespace>:<name>[@<semver>]", …] — abstract capabilities the package advertises.
20 spec: [obsoletes].packages = [ pkgrefs… ] —…
[obsoletes].packages = [ pkgrefs… ] — the package supersedes these; the solver flags them for removal on upgrade.
21 quote from the specification
[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 spec: Additive only
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 spec: Default features
Default features.default = [...]lists features active when no override is given.--no-default-featureson the install / update CLI omits them.
25 spec: Feature unification across the dep graph
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 spec: vibe install <pkgref> [--features <a,b,c>] [--no-default-features]…
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 quote from the specification
Decision. vibe.toml carries an array of registries:
29 spec: Decision: [[mirror]] entries are parallel alternative…
Decision.[[mirror]]entries are parallel alternative URLs for a specific registry (or*for any). During fetch:
30 spec: Decision: Adopt a sidecar file naming…
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 spec: A localised file is the canonical…
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 spec: Critical invariant: every package must ship…
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.
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 |
[[command]] |
id, optional description and a typed script handler: an explicit vibe run entry |
projects/workspace hosts only |
[[embedded_source]] |
an immutable external source a package refers to without vendoring it | bridge packages |
36 spec: [boot_snippet] (package-role) drops the filename field…
[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 spec: The MVP section is an array-of-tables…
The MVP section is an array-of-tables, matching the manifest's existing[[requires_any]]/[[registry]]/[[mirror]]shape:
38 spec: vibe run <id> -- <args…> dispatches…
vibe run <id> -- <args…>dispatches an explicit host-owned[[command]]from the selectedvibe.toml. The first handler is{ kind = "script", base = "…" }, using the same cross-platform.sh/.ps1selection as lifecycle scripts, a project-contained canonical path, exact argument forwarding, inherited operator environment,VIBE_PROJECT_ROOT, and the exactVIBE_EXECUTABLE; the child exit code passes through. A command is legal only on a project/workspace host, never in a publishable package, so installing a dependency cannot inject an npm-style ambient script. There is deliberately no shell-string form. This is the explicit typed-action posture of NEXT-A11/A14 and leaves the command id stable when a later implementation lowers its handler to the shared recorded-artifact plane.
39A 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.
40 spec: Decision: A package declares…
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.
41 spec: When present, only matching files…
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.
42 spec: A reference-backed bridge MAY select…
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:
43 spec: source and embedded_source name a manifest…
sourceandembedded_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.
44 quote from the specification
A code-bearing package declares each shipped tool in its vibe.toml:
45 spec: The [[mcp_server]] table (§2.2) is legal…
The[[mcp_server]]table (§2.2) is legal only in this kind — the kind IS the taxonomy, enforced byManifest::validate, not advisory.
46 quote from the specification
Hooks live in a package-role[hooks]table invibe.toml:
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; [[navigation.section]] rows with id and title for the folders of the page tree; [[navigation.chapter]] rows with id, title, pages and an optional appendix for the learning path, which a translation names with id and title only |
doc |
[glossary] |
page: the document path of the page that defines the package's words; each top-level section of that page is one entry |
doc |
[media] |
icon, banner, preview: source image files within the card limits |
every kind |
49 spec: [[documents]] is REQUIRED in a doc…
[[documents]]is REQUIRED in adocpackage, may list several subjects, and itsversionis a semver constraint.
50 spec: [documentation] in the subject names coordinates…
[documentation]in the subject names coordinates without versions;primarynames at most one package,officialany number.
51 spec: A translation of documentation…
A translation of documentation is a separate package of kind doc:
52 spec: Images are source files…
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.
53 spec: A documentation package MAY declare [navigation]…
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.
54 spec: A documentation package MAY declare…
A documentation package MAY declare a learning path in[navigation]:[[navigation.chapter]]rows, each with anid, atitleandpages— the document paths the chapter holds, in reading order — and optionallyappendix = truefor a chapter of pages a reader looks things up in rather than reads through. The rows in their written order are the path: followed from the first page of the first chapter to the last page of the last, it meets every page of the package once. The path is written for people and moves no other order:pagesin the page manifest and thellmsfiles keep the layer law (spec://org.vibevm.core/vibevm/common/PROP-048#THE-LAYER-LAW), and the page manifest carries the path beside them asnavigation.chapters.
55 spec: A documentation MAY declare its glossary
A documentation MAY declare its glossary (added 2026-09-26): a top-level table[glossary]withpage, the document path of the page that defines the package's terms. That page is the glossary. Each of its top-level sections is one entry: the section's id is the entry's anchor, itstitleis the term, and its first paragraph is the definition; more paragraphs and cited rules may follow. Everything the pipeline, the reader and the tools do with terms — the style checks of##STYLE-LINT, the cards of##READER-GLOSSARY-CARD— they do with the declared glossary, and a package that declares none has none; the pathglossary/index.xmlmeans nothing by itself.
A complete example
56
57The manifest of this manual, generated from the package itself, shows a doc package with a card, a subject and a skill.