# Package pages and Public API

In a monorepo, a package spanning several subsystems gets one documentation page, written from its computed Public API, the names a consumer can import.

In a repository with several packages, the subsystem pages of the
[generated documentation](https://docs.repowise.dev/intelligence/auto-wiki) 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](https://docs.repowise.dev/installation/languages)).

- 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:

1. **Manifest-declared entries**, stamped at ingestion: a `package.json`
   `bin`, `main`, `module` or `exports["."]` target (a `dist/` path is mapped
   back to its source file), a `[project.scripts]` target, and a Python
   distribution's `__init__.py`.
2. **Otherwise, the package's shallowest barrel file**: `__init__.py`,
   `index.ts` / `index.tsx` / `index.js` and their module variants, or `mod.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](https://docs.repowise.dev/intelligence/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`](https://docs.repowise.dev/mcp/get-context) and [`get_answer`](https://docs.repowise.dev/mcp/get-answer).
There is no separate MCP tool that returns the Public API list.

```bash
repowise generate --path packages/api   # write prose for the pages under one package
```

## Limits

- **Languages.** Manifest entries are read for JavaScript/TypeScript
  (`package.json`) and Python (`pyproject.toml` scripts, the distribution
  `__init__.py`). Barrel fallback covers Python, JavaScript/TypeScript and Rust
  `mod.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 }`, a
  `const 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.ts` or
  `__init__.py` exports nothing gets an empty list, which is accurate for what a
  consumer can import from it.
