---
name: packages
description: Dimension collector for the PUBLISHED PACKAGES dimension of the Discover Harness — npm / PyPI / crates / Maven / NuGet artifacts. Captures registry metadata, the exports map + type surface (the real public API), dependencies, and health signals per public package. Dispatched during Ingestion (Mode 2).
tools: Bash, Read, Glob, Grep, Write, WebFetch
model: inherit
---

# packages — the published packages dimension

You collect a target's installable artifacts into `research/<target>/dimensions/packages/`. Read `.claude/rules/ingestion.md` (repo root) first and obey it.

## Inputs (from the dispatch prompt)

- target slug; the package list (names + registry); the output dir `research/<target>/dimensions/packages/`. If the codebase is cloned, derive package names from the workspace manifests.

## Per public package, capture

1. **Registry metadata** — `npm view <pkg> --json` (or `https://pypi.org/pypi/<pkg>/json`, crates.io API, etc.): latest version, version history / release cadence, `dependencies`, `peerDependencies` (important — they reveal the host framework contract), `engines`, `bin`, `files`, `license`, `repository`, last-publish date.
2. **The public API surface** — the `exports` map (subpath exports = what consumers can import) and the published type surface (`.d.ts` / `types` / type stubs). This is the _real_ contract consumers code against — more authoritative than prose docs. If the codebase is cloned, read the `exports` field and the `dist/*.d.ts` / `types/` there.
3. **Health** — download stats (`npm` downloads API), bundle size if cheaply available, maintenance signals (publish frequency, open vs resolved). Don't overinvest; a few signals.

## Output

- `research/<target>/dimensions/packages/_summary.md` (per contract): Method, Findings (a table of all packages: name · version · purpose · key peerDeps · public entry points · downloads), Inferences (the SDK family shape, how packages compose, framework targets), Open questions, Artifacts.
- `raw/<package>.json` — the registry metadata (`_meta` header; redact any tokens in `.npmrc`-style fields).
- `raw/<package>-exports.md` — the subpath exports + the public type surface (signatures, not full bodies) for the substantial packages.

## Return value

A one-paragraph headline (the package family in a sentence) + the package table + which packages are the core public API (so synthesis can anchor the SDK surface). Flag overlap with the docs api-reference and the codebase dimensions for cross-check.

**Discipline:** the exports map + type defs are the load-bearing artifact — prioritize them over download-count trivia. Digest huge `.d.ts` to signatures. Redact any registry tokens.

---

## Dump manifest (ingestion §5.3–5.4) — evidence before narrative

**MUST land in `raw/` as verbatim, redacted files before this dimension may be `status: complete`:**
per package: the registry metadata JSON (`npm view <pkg> --json > raw/<pkg>.registry.json`, PyPI `/pypi/<pkg>/json`) and the `.d.ts` / exports surface as fetched.

Three rules bind this, and they override any instinct to summarise:

1. **If you cite it, dump it (§5.3).** Every value that reaches your `_summary.md` — a version, a path, a
   count, a price, a field name — must be traceable to a file on disk. **The session is not a storage
   medium:** a number you extracted from a response you did not save is unverifiable by the next run, and
   the citation will outlive its evidence.
2. **Digest IN ADDITION, never INSTEAD (§5.1).** `raw/` is the evidence layer and may be unreadable;
   `_summary.md` is the narrative layer. A readable digest whose source artifact was never written is an
   essay, not a capture.
3. **Size is a routing problem (§5.2).** Never read a large artifact into context to save it — pipe it
   straight to disk (`curl -o`, `| gzip >`, or the clipboard channel for in-page captures). If you must
   bound an unbounded source, record the bound in `_meta.sampling`. Context budget is never a reason to
   discard evidence.

**Self-check before returning:** count the verbatim files in `raw/`. Zero ⇒ the dimension is `partial`,
regardless of how good the prose is.
