@pumicejs/docs
v0.0.1
Published
Documentation generator for pumice.js APIs (HTML, OpenAPI 3.1, Markdown, MCP).
Downloads
77
Maintainers
Readme
@pumicejs/docs
Documentation generator for pumice.js APIs.
Reads the manifest exposed by ClientGenerationPlugin (default GET /@client) and emits:
- a static HTML docs site with sidebar nav, fuzzy search, dark mode, code samples in 5 languages, and an in-browser Try It panel
- an OpenAPI 3.1 spec — drop into Postman, Insomnia, Bruno, Swagger UI, Redoc, Stoplight, and any of the 30+ codegen targets
- a Markdown reference (GitHub-friendly)
- the raw DocModel JSON (escape hatch for custom rendering)
- an MCP / AI tools manifest so Claude or GPT can call your API directly
Plus two CI helpers:
lint— documentation coverage report (descriptors, response schemas, field descriptions, undeclared throws), with a--fail-underthresholddiff— classifies changes between two manifest snapshots as breaking / non-breaking / info, with a--fail-on-breakingexit code
Install
npm install -D @pumicejs/docsRequires Node.js >=18.
Quick start
With your pumice.js server running on http://localhost:3000:
# HTML docs into ./api-docs
npx pumice-docs generate -u http://localhost:3000 -f html -o ./api-docs
# OpenAPI 3.1 (use this with Postman / Swagger UI / etc.)
npx pumice-docs generate -u http://localhost:3000 -f openapi -o ./openapi.json
# Live preview that auto-refreshes on manifest changes
npx pumice-docs serve -u http://localhost:3000 -p 8787Open the generated api-docs/index.html in a browser, or visit http://localhost:8787 for the live preview.
CLI
generate
pumice-docs generate [options]
-u, --url <url> API base URL or local manifest JSON file
(default: http://localhost:3000)
-o, --output <path> Output file or directory
-f, --format <format> html | openapi | markdown | json | mcp
(default: html)
-m, --manifest-path <path> Manifest endpoint path (default: /@client)
-c, --config <path> Path to a pumice-docs config file
-d, --debug Verbose loggingThe -u flag accepts either a URL (live fetch) or a path to a manifest JSON file (offline generation — useful for CI artifacts).
serve
pumice-docs serve [options]
-u, --url <url> API base URL (default: http://localhost:3000)
-m, --manifest-path <path> Manifest endpoint (default: /@client)
-p, --port <port> Listen port (default: 8787)
--poll <ms> Manifest poll interval (default: 3000)
-c, --config <path> Path to a pumice-docs config fileThe preview re-fetches the manifest every --poll ms; when a change is detected the page hard-reloads.
lint
pumice-docs lint [options]
-u, --url <url> API base URL or local manifest JSON file
-m, --manifest-path <path> Manifest endpoint (default: /@client)
--json Machine-readable output
--fail-under <score> Exit 1 if coverage < score (0-100)Reports a 0-100 coverage score weighted by route descriptors (40 pts), response schemas (30 pts) and field descriptions (30 pts), plus an issue list.
diff
pumice-docs diff <before> <after> [options]
-f, --format <format> text | markdown (default: text)
--fail-on-breaking Exit 1 if any breaking change is detected
-o, --output <path> Write the report to a file instead of stdoutBoth <before> and <after> accept either a URL or a local manifest JSON file.
Config file
Any of pumice-docs.config.json, pumice.docs.json, or .pumice-docs.json in the working directory will be picked up automatically (or pass --config <path>):
{
"url": "http://localhost:3000",
"manifestPath": "/@client",
"output": "./api-docs",
"format": "html",
"branding": {
"title": "Acme API",
"description": "REST API for Acme widgets",
"intro": "Authenticate with a bearer token issued by the dashboard.",
"logo": "https://acme.example/logo.svg",
"color": "#0ea5e9",
"attribution": "© Acme Inc."
},
"groupTitles": {
"users-id": "User detail",
"(auth)-billing": "Billing"
},
"hideRoutes": [
"GET /admin/internal",
"POST /admin/internal/refresh"
]
}Every field is optional. The footer always shows Generated with pumice regardless of branding.attribution.
Output formats
HTML (default)
A vanilla single-file SPA — no framework, no build step, no runtime server needed. Drop the output into any static host (GitHub Pages, Cloudflare Pages, S3, Netlify, Vercel).
Includes:
- sidebar grouped by route file with method-colored badges
- press
/to focus the search box - dark / light theme toggle (persisted in
localStorage, respects system preference on first load) - per-route schema tables for path / query / headers / body / file uploads
- success and error response examples (wrapped in your envelope)
- code samples in tabs: pumice client, Node fetch, curl, Python
requests, Pythonhttpx - expandable Try It panel that POSTs from the browser using your declared schema as the default payload
OpenAPI 3.1
Standards-compliant spec with $ref-deduplicated component schemas, multipart support for file uploads, bearerAuth on auth-required routes, and your success / error envelopes correctly modeled. Compatible with:
- Postman / Insomnia / Bruno / Hoppscotch (import as collection)
- Swagger UI / Redoc / RapiDoc / Stoplight Elements (render as alternative docs)
- 30+ language codegens via
openapi-generator,oapi-codegen,kiota, etc.
MCP / AI tools
Emits a tools.json whose tools[] entries map 1:1 to your routes, with a JSON Schema input describing path / query / headers / body. Pass directly to:
- Anthropic's Messages API
toolsparameter (Claude tool use) - OpenAI Chat Completions
toolsparameter - any MCP server wrapping your API
Each tool also carries an x-pumice field with the HTTP method, path template, and auth requirement so a wrapper can perform the actual call.
Markdown
A single self-contained .md file with a TOC, per-route sections, and collapsible code samples. Renders cleanly in GitHub, GitLab, and most static-site generators (Docusaurus, VitePress, MkDocs, Hugo, Jekyll).
JSON
Raw DocModel — feed it to your own templating engine if none of the above fits.
Programmatic API
Everything the CLI does is also exported from the package root:
import {
loadManifestFromSource,
normalizeManifest,
renderHtmlDocs,
renderOpenApi,
buildCoverageReport,
diffManifests,
} from "@pumicejs/docs";
const manifest = await loadManifestFromSource("http://localhost:3000", "/@client", logger);
const model = normalizeManifest(manifest, { baseUrl: "http://localhost:3000" });
renderHtmlDocs(model, { outputDir: "./api-docs" });
renderOpenApi(model, { output: "./openapi.json" });
const report = buildCoverageReport(model);
console.log(`Coverage: ${report.score}/100`);CI recipes
Block PRs with breaking API changes
- name: Save baseline manifest
run: curl -fsSL https://api.example.com/@client > /tmp/main.json
- name: Build and start the app under test
run: |
npm run build
npm start &
npx wait-on http://localhost:3000
- name: Diff against main
run: npx pumice-docs diff /tmp/main.json http://localhost:3000 --fail-on-breakingEnforce a documentation-coverage floor
- run: npx pumice-docs lint -u http://localhost:3000 --fail-under 80Publish an OpenAPI spec on every release
- run: npx pumice-docs generate -u https://api.example.com -f openapi -o ./openapi.json
- uses: actions/upload-artifact@v4
with: { name: openapi, path: openapi.json }License
ISC
