Decision rule
supaschema uses thefiles allowlist in package.json as the npm package boundary.
There is intentionally no root .npmignore.
npm treats
files as an allowlist. A root .npmignore is a denylist. This
repository has many maintainer-only support files, so allowing known package
contents is safer than trying to exclude everything that should not publish.Four surfaces
| Surface | Source of truth | Purpose |
|---|---|---|
| npm tarball | package.json files | Files downloaded into node_modules/supaschema |
| Consumer setup | supaschema init | Files written or merged into the installing project |
Public npx skills source | skills/supaschema | Portable Agent Skill context installed by the Skills CLI |
| Public repository | Git-tracked public-safe files | Source, docs, examples, tests, CI, and release evidence that can be public |
| Private maintainer workspace | Private repository or intentionally untracked local files | Private automation, credentials, plans, scratch output, and non-public operator context |
npm package
The package allowlist includes only runtime and install assets: the built CLI and library, config schema, README/license files, and the explicit supaschema consumer agent bundle. Do not add broad repo directories to the allowlist just because a single file is needed. Add the narrowest file or directory that matches the consumer contract. Public docs, examples, benchmarks, corpus fixtures, source files, tests, services, and maintainer scripts stay out of the npm tarball. They belong in the public repository or hosted docs when they are product evidence, and in a private maintainer workspace when they are not. Generated build caches must not live inside an allowlisted directory: a broad entry likedist ships everything beneath it, so write a tsBuildInfoFile to .tmp/ rather than dist/. tests/package-contents.test.ts fails if any .tsbuildinfo, source file, public-support directory, or maintainer tooling reaches the tarball.
Agent bundle boundary
The exact Claude, Codex, and shared agent surfaces live in Agent bundle. Keep that page as the reader-facing owner for agent bundle contents. Keep this page focused on package mechanics, tarball inclusion, consumer setup, and maintainer-only exclusions.Public npx skills source
skills/supaschema is a generated mirror of the canonical .claude/skills/supaschema workflow. It exists so users can install portable workflow context without installing the npm package:
.agents/skills and .claude/skills; this repository uses those locations for maintainer mirrors while developing supaschema itself.
That command does not install hooks or rules. Agent Skills are SKILL.md folders with optional scripts, references, and assets; the supaschema rule and hooks need project files and Claude/Codex hook registration. Those surfaces ship as raw files under node_modules/supaschema/agent-bundle/ and are installed only after the user approves AI-agent enforcement. Package install and default supaschema init do not invoke the Skills CLI and do not copy active .agents, .claude, or .codex surfaces.
Consumer setup
supaschema init owns setup for consuming projects after package install. The install contents list lives in What’s included; keep it there instead of duplicating it across release and packaging references.
The supaschema init command performs this setup through bin/scaffold.mjs (a dist-free module that ships in the bin allowlist entry). Run it through the consuming package manager’s local runner from the package directory that owns the schema workflow. The command is idempotent, so it is also the repair path when config needs refresh. The shared scaffold creates supaschema.config.json from the generated config contract when it is absent, rewrites it only for explicit repair, and records unresolved path confirmation in .supaschema/install.json only when detected paths still need human confirmation. Resolved installs do not create .supaschema/; durable project defaults belong in supaschema.config.json.
The same scaffold installs no active agent surfaces by default. The raw AI-agent bundle remains available under agent-bundle/ in the package and can be installed on demand with supaschema init --agent-bundle after review.
Do not copy maintainer workspace tooling into consumer projects unless the consumer contract explicitly changes and package tests are updated at the same time.
Maintainer workspace
Repo-local editor, language-server, Python, MCP, Code Atlas, FastMCP, lint, test, guard, and release tooling is for developing supaschema itself. The private Python/FastMCP workflow, when present locally as.github/workflows/python.yml, stays untracked with the private FastMCP service. Public GitHub Actions workflows must not require ignored maintainer-only service files that are absent from a clean checkout.
These files stay out of the package allowlist unless they become runtime product assets or consumer install outputs. If any of them are not public-safe, they must be moved to a private repository or intentionally untracked local path before the public repository is pushed.
Public repository boundary
The public repository may include public-safe product source, public docs, public examples, tests, CI, and release evidence. It must not include credentials, customer data, private plans, private operator context, or maintainer-only automation that is not intended for public review..gitignore is the prevention layer for generated and local-only files, not an access-control layer. Git’s own manual says ignore rules apply to intentionally untracked files and do not affect files already tracked by Git; tracked files must first be removed from the index before ignore rules prevent reintroduction.
That means the correct public-repo sequence is:
Classify
Decide whether each surface is public product source/docs/examples, public
verification evidence, or private maintainer context.
Move or untrack private files
Move private surfaces to a private repository or remove them from the public
index with
git rm --cached after verifying the public build and release no
longer depend on them.Why not .npmignore?
npm supports.npmignore, but it is a blocklist. Blocklists are fragile in a repo that has many development surfaces and only a small, deliberate consumer surface.
npm also falls back to .gitignore when .npmignore is missing and no files allowlist is present. Because supaschema does have a files allowlist, the root package boundary should stay in package.json.
Sources:
- npm package.json files
- npm publish package contents
- GitHub changelog: upcoming npm v12 changes
- npm developer guide
- Git gitignore manual
- GitHub repository visibility
- GitHub sensitive data removal
Consumer lifecycle verification
The test owners and release smoke script prove the package surfaces, and they move together with this page and the guards (no single test should grow to cover another’s surface):| Phase | Owner | Proves |
|---|---|---|
| Download | tests/package-contents.test.ts | The shipped file list, package-size budget, and broad-directory denylist so docs, examples, benchmarks, corpus fixtures, source, tests, services, and maintainer scripts cannot silently bloat the download. |
| Setup | tests/database-url.test.ts | The shared scaffolder creates the consuming project setup (config, schema/migration dirs, agent bundle, install manifest). |
| Use | tests/consumer-lifecycle.test.ts | The full chain end to end: pack, npm install the tarball into a throwaway project, edit a schema in the scaffolded tree, then run the installed supaschema binary and confirm an accurate, replay-safe migration and accurate generated types. |
| Package-manager smoke | scripts/release/package-smoke.mjs | The packed tarball installs and initializes through the supported consumer package managers and workspace recovery paths. |
dist/cli.js needs its runtime dependencies. This is the npm-documented “install the tarball, run the installed bin” pattern.
The published package must not define preinstall, install, postinstall, or prepare scripts. Consumer setup runs through explicit supaschema init, so pnpm, Bun, Yarn, and npm installs do not require build-script approval to download the CLI.
npm run release:verify is the release-facing entry point. It calls the package-manager smoke after the package checks, so use that command for release readiness.
A local registry (Verdaccio) publish-then-install flow is the optional
high-fidelity tier for exercising registry resolution, dist-tags, and package
manager download behavior. It is intentionally not used by default: this
is a single-package CLI whose
bin is a small launcher of dist, so a
tarball install is hermetic, offline, and cross-platform without the extra
service.
