In a repository with several packages, the subsystem pages of the generated documentation follow how the code clusters, which does not always match package boundaries. Package pages close that gap: a package gets a page about the whole package, and that page is written from what the package publishes, not only from the files that rank highest inside the repository.
When a package gets its own page
A package root is a directory with a package manifest (package.json,
pyproject.toml, Cargo.toml and the other manifests in the
language registry).
- A package whose files span two or more subsystem groups always becomes a chapter page covering the whole package, at any depth and whatever its share of the repository.
- A package that fits in one group already has that group's page.
- Several thin sibling packages rolled up into one group keep that shared page.
A chapter page links down to every page it is the nearest chapter of, so a leaf page several directories below the package root is still linked from it.
The computed Public API
The Public API of a package is what a consumer can import from it. Repowise computes it from the parsed imports and exports, with no model involved.
It starts from the package's front door:
- Manifest-declared entries, stamped at ingestion: a
package.jsonbin,main,moduleorexports["."]target (adist/path is mapped back to its source file), a[project.scripts]target, and a Python distribution's__init__.py. - Otherwise, the package's shallowest barrel file:
__init__.py,index.ts/index.tsx/index.jsand their module variants, ormod.rs.
From each root it follows re-exports: export ... from, export * as ns,
aliases, a Python package's __init__.py imports and wildcard imports. A
module's literal __all__ is honoured when present. Every entry records its
name, kind, declaring file, and when it is a second name, which symbol it
aliases.
Because the list comes from the front door, a class that consumers import but nothing inside the repository uses is still on it. That class is often the reason the package exists, and it is the one a ranking by in-repo imports misses.
Where it shows up
- Package and subsystem pages, when written by a model. The page prompt lists the Public API ahead of entry points and key files, and asks the model to name the central entries and say what each is for, without inventing members. Each entry carries its signature and first doc line while a budget of 10,000 tokens lasts; entries past the budget keep their name.
- Not on a keyless page. Without a model the package page is a structural
stub and does not print the computed list. See
Deterministic wiki for what a keyless
run renders and how to add prose later with
repowise generate.
This is separate from the Public API table on a file page, which lists the public symbols one file declares. File pages are structural and carry that table with or without a key.
Agents read package pages the same way as any other documentation page, through
get_context and get_answer.
There is no separate MCP tool that returns the Public API list.
repowise generate --path packages/api # write prose for the pages under one packageLimits
- Languages. Manifest entries are read for JavaScript/TypeScript
(
package.json) and Python (pyproject.tomlscripts, the distribution__init__.py). Barrel fallback covers Python, JavaScript/TypeScript and Rustmod.rs. A package in a language with neither, such as Go, Java or C#, gets no computed Public API, and its page is written from its files as before. - Parser gaps. Measured against the TypeScript compiler's export list on a
large TypeScript package, the computed list held 459 of 466 names (98.5%) and
nothing outside that set. The misses: a deferred
export type { X }, aconst a = b;alias export, and a name re-exported from an npm package outside the repository. - An empty barrel publishes nothing. A package whose root
index.tsor__init__.pyexports nothing gets an empty list, which is accurate for what a consumer can import from it.