the format
The docspack package format
A documentation package is an ordinary npm package whose payload is Markdown. Everything a
publisher writes and a consumer reads is on this page; the machine-readable form is
/schema/v1.json, which is what
$schema in every generated manifest points at.
docspack build writes all of this for you. The format is documented
because a package is publishable without the CLI, and because a consumer other than
docspack should be able to read one.
Naming
Two name shapes are discoverable, and discovery is a pure name check against
package.json — no registry call, no manifest fetch, nothing that can
fail while offline.
-
@vendor/docspack— published by whoever owns the scope. Trusted: its content is presented to an agent as documentation. -
@docspack-community/<name>— published by anyone. Every answer drawn from one is labelled(community)and marked untrusted data.
One pack per npm scope is deliberate, and it is the constraint to design a package layout
around. It is what makes @vendor/docspack derivable from a
dependency's own name, so a project's documentation set is a function of its
package.json alone. A vendor shipping two unrelated products under
one scope documents both in one pack, or publishes the second under a scope of its own.
Layout
.llms/ is the payload and must be listed in the package's
files. Omitting it publishes a package that installs cleanly and
indexes nothing — docspack doctor treats that as an error.
@vendor/docspack/
├── package.json name, version, and the docspack build settings
├── llms.txt human-readable table of contents
└── .llms/
├── manifest.json every chunk, its file, size, tags and entities
└── chunks/
├── overview.md
└── webhooks-signing.md manifest.json
The one file a consumer must read. It is the whole index of the package: a reader budgets a
response from tokens before opening a single chunk file.
| Field | Type | Meaning | |
|---|---|---|---|
name | string | required | npm package name, e.g. @stripe/docspack. |
version | string | required | Must match the version in package.json. |
chunks | array | required | Every retrievable unit of documentation in the package. |
Each entry in chunks
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | Unique within the package; used to build the chunk_id in the index. |
file | string | required | Path relative to .llms/. Must not escape that directory. |
tokens | integer | Approximate token count, used to budget a response. Estimated when absent. | |
tags | array | Search terms indexed alongside the content. | |
entities | array | Identifiers the chunk documents, e.g. Stripe.setApiKey. |
{
"$schema": "https://docspack.dev/schema/v1.json",
"name": "@acme/docspack",
"version": "1.4.0",
"chunks": [
{
"id": "webhooks-signing",
"file": "chunks/webhooks-signing.md",
"tokens": 412,
"tags": ["webhooks", "signature", "security"],
"entities": ["client.verifySignature", "WebhookEvent"]
}
]
} Rules a consumer enforces
-
A chunk
fileresolves inside.llms/or it is refused. A manifest is third-party input, so this is a security boundary rather than a convenience check. -
The installed
package.jsonversion wins over the manifest's when the two disagree, and the mismatch is reported. -
Chunk ids are unique within a package and match
^[A-Za-z0-9][A-Za-z0-9._-]*$. The id an answer is headed with is<name>@<version>/<id>. - Unknown fields are accepted and ignored. An invented field is not an error, so it is also not a feature — nothing reads it.
Authoring controls
Front matter carries title and tags for a
whole document. A single section takes its own with an HTML comment under the heading,
which is what to reach for when one page holds eighty of them:
## Two-column layout
<!-- docspack: tags=grid,columns -->
<!-- docspack: entities=TwoColumn --> Tags are weighted above prose in the ranking, so they are the lever that aims one chunk at one question.
Next
- /schema/v1.json — the JSON Schema, versioned with the format
- Authoring a package — writing one with the CLI
- /llms.txt — the agent-facing summary of all of it