Skip to content
internal/manifest
On this page

Generating and reading a project's manifest: the JSON record of its identity, version, its pages with their heading anchors, and its published posts.

#internal/manifest

#internal/manifest

Package manifest generates and reads a project's manifest: the JSON record of what a build published -- the project's identity and version, its pages with their heading anchors, and its posts.

The manifest is what a reader that cannot run the build asks. The assembly composes a site out of one manifest per project, the editor draws its outline and its link targets from the pages' headings, and the slug immutability check reads the committed copy out of git to see what a post was published as.

#The document's bytes are the contract

The manifest is committed, so every byte of it shows up in a diff. Its keys are written in declaration order rather than sorted, two-space indented, with every non-ASCII character escaped -- the shape the Python encoder wrote, reproduced here so the port does not rewrite every project's committed manifest on its first run. A write is skipped entirely when nothing but the generation timestamp would change.

#The reader is tolerant

Compat is the one door every read path goes through. It takes the fields it knows and ignores every other key, so a manifest written by a later selfdoc still reads here; a schema_version above the supported one is the single hard refusal, because that declares a document this reader cannot claim to understand.

#DefaultTheme

Go go
const DefaultTheme = "minimal"

DefaultTheme is the theme a project's manifest records when its config names none. It is the same default the build applies, and the assembly's chrome reads this field to decide which stylesheet a project's pages reference.

#SchemaVersion

Go go
const SchemaVersion = 1

SchemaVersion is the manifest format this package writes, and the highest it reads. A document declaring more is refused rather than read on this version's terms.

#DefaultOutputName

Go go
const DefaultOutputName = "manifest.json"

DefaultOutputName is the filename a project's manifest is written under inside selfdoc's generated-state directory.

#Heading

Go go
type Heading struct

Heading is one heading on a page, with the element id the built page carries for it.

#Page

Go go
type Page struct

Page is one documentation page as the manifest records it.

#Post

Go go
type Post struct

Post is one blog post as the manifest records it.

#Manifest

Go go
type Manifest struct

Manifest is a project's published record.

#Doc

Go go
type Doc struct

Doc is one resolved docs page in the shape this package reads it.

It is the docs resolution's per-page tuple, narrowed to the three members the manifest uses: the frontmatter for the title and the type, the resolved content for the headings -- so a directive-generated heading is recorded -- and the raw content for the title fallback.

#ToKebab

Go go
func ToKebab(name string) string

ToKebab converts a name to a kebab-case slug: lowercased, with spaces and underscores becoming hyphens, every other non-alphanumeric character dropped, runs of hyphens collapsed and the ends trimmed.

#Generate

Go go
func Generate(

Generate builds a Manifest from a project's config and its resolved docs, and writes it to inside selfdoc's generated-state directory.

The write is skipped when everything but the generation timestamp is unchanged, so a gen over untouched content does not dirty the working tree. The returned Manifest is what was built either way.

#Compat

Go go
func Compat(data map[string]any, source string) (*Manifest, error)

Compat builds a Manifest from a parsed manifest document.

Every read path goes through here: the file reader, the git reader, and the assembly's own raw decode. It is a tolerant reader -- it takes the fields it knows about and ignores every other key, which is the contract that lets a later selfdoc add a field without breaking an older reader.

source names where the document came from, for the error message; pass "" when there is nothing useful to name. A schema_version above SchemaVersion is an error: this reader cannot honestly read a document whose format it does not know.

#Load

Go go
func Load(path string) (*Manifest, error)

Load reads a manifest file and returns what it records.

It returns a nil Manifest and a nil error when the file does not exist -- "this project has no manifest" is an answer, not a failure.

#LoadFromGit

Go go
func LoadFromGit(dirPath string, handle *effects.Handle) (*Manifest, error)

LoadFromGit reads the committed manifest out of the repository's HEAD, bypassing the working-tree copy.

This is what the slug immutability check compares against: a post's slug must match the one it was published under, and by the time the check runs gen has already rewritten the on-disk manifest with the new slug.

It returns a nil Manifest and a nil error when the directory is not a repository, when the repository has no commits, or when the manifest has never been committed.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • claudewheel A TUI Claude Code Launcher that lets you have more than one profile, manage sessions lifecycle, pick the exact CC version, model to use (even older unlisted ones), pick which GitHub account to use, etc.
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search