Skip to content

docs: publish the guide as a VitePress site - #29

Merged
btravers merged 2 commits into
mainfrom
docs/vitepress-site
Aug 7, 2026
Merged

docs: publish the guide as a VitePress site#29
btravers merged 2 commits into
mainfrom
docs/vitepress-site

Conversation

@btravers

@btravers btravers commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

docs/ becomes a workspace of its own — a VitePress site organised by the four Diátaxis modes and deployed to https://btravstack.github.io/entity/, matching how every other btravstack project ships its documentation. Modelled on btravstack/unthrown.

Content

The existing prose is carried over unchanged and redistributed:

Was Now
tutorial/getting-startednew
how-to/*.md (4) unchanged, plus title/description frontmatter
reference.md reference/{declaration,schemas,entry-points,errors,types}
explanation.md explanation/{why-entity,no-io,sealed-construction,immutability,computed-fields,tags-and-identity,errors-are-values,peer-dependencies}
api/index.md + TypeDoc-generated api/entity/

The tutorial is the one piece of new writing: ten steps from nothing to an entity that is branded, declared, created through a factory, failed as a Result, constrained by an invariant, given a computed field and a getter, updated, and projected to the wire.

Cross-links were rewritten to site routes; every anchor referenced was checked against the built HTML.

Site

  • docs/.vitepress/config.ts — base /entity/, local search, sitemap, per-page canonical + OG/Twitter via transformPageData, JSON-LD, edit links, and one shared sidebar across all four sections so any page reaches any other.
  • theme/index.ts wraps @btravstack/theme; custom.css sets a single --accent: #ee9cc4 (the mascotte's blush) that the shared theme derives every other shade from, plus a masked hero glyph — a record card, stamped validated.
  • public/logo.svg (favicon, the mascotte lifted out of its frame) and four feature icons.
  • srcExclude keeps the git-ignored docs/superpowers/ scratch out of the site and the sitemap.

TypeDoc runs from docs/, not from the package

This is the one deliberate divergence from the sibling repos, and it is forced rather than stylistic.

The catalog pins typescript: 7.0.2 — the native port. It ships lib/tsc.js and no typescript.js, so the compiler API TypeDoc drives does not exist there. The usual arrangement (a build:docs script in the package, output copied in by scripts/copy-docs.ts) therefore cannot run at all.

Instead TypeDoc runs from the docs workspace against ../packages/entity/src/index.ts, with its own TypeScript 6.0.3 from a new named typedoc catalog. It writes straight into docs/api/entity/, which removes the copy step entirely. The reason is recorded inline in pnpm-workspace.yaml and in CONTRIBUTING/CLAUDE.md.

Deployment

deploy-docs.yml in the single-version shape: chained off a green CI run on main, plus workflow_dispatch. CI and Release use btravstack/config's reusable workflows and do their own setup, so .github/actions/setup is added for the one workflow that runs its own steps.

Note

The github-pages environment needs to exist with a main branch policy, and Pages needs to be set to deploy from GitHub Actions, before the first run succeeds.

Verification

Full gate green: format --check, lint, typecheck, test (145 passing), knip, build. pnpm --filter ./docs exec turbo build — the exact command the workflow runs — was verified locally, and all 23 pages serve 200 with the nav, sidebar and sitemap correct.

The site was not viewed in a browser (the Chrome extension was unavailable), so the visual result rests on the emitted HTML/CSS rather than on a screenshot. Worth a look at the hero before merging.

Included: a patch changeset for the package README's link change.

🤖 Generated with Claude Code

`docs/` becomes a workspace of its own — a VitePress site organised by the
four Diátaxis modes and deployed to https://btravstack.github.io/entity/,
matching how every other btravstack project ships its documentation.

The existing prose is carried over unchanged and redistributed: `reference.md`
splits into `reference/{declaration,schemas,entry-points,errors,types}`,
`explanation.md` into eight pages under `explanation/`, and the four how-to
guides gain frontmatter. A `tutorial/getting-started` page is new, taking a
reader from nothing to an entity that is created, validated, updated and
serialised.

TypeDoc runs from `docs/` rather than from `packages/entity/` as it does in the
sibling repos, with its own TypeScript from a named `typedoc` catalog. That is
forced, not stylistic: the catalog's `typescript: 7.0.2` is the native port and
ships no JS compiler API for TypeDoc to drive — so the usual `build:docs` +
copy-docs arrangement cannot work here. TypeDoc writes straight into
`docs/api/entity/` instead, which drops the copy step entirely.

Deployment is the single-version shape: `deploy-docs.yml` chains off a green CI
run on main. CI and Release use btravstack/config's reusable workflows and do
their own setup, so the `.github/actions/setup` composite is added for the one
workflow that runs its own steps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 7, 2026 16:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR converts docs/ into a dedicated VitePress workspace (Diátaxis-structured) with TypeDoc-generated API pages and adds a GitHub Pages deployment workflow, updating repository/package READMEs and tooling config to match the new docs setup.

Changes:

  • Add a docs/ workspace (VitePress + TypeDoc) and reorganize documentation into tutorial/how-to/reference/explanation routes.
  • Add a Pages deployment workflow (plus a local composite setup action) and wire docs build outputs into Turbo.
  • Update READMEs/CONTRIBUTING and repo config (pnpm-workspace.yaml, knip.json, .gitignore) to support the new docs pipeline.

Reviewed changes

Copilot reviewed 37 out of 44 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
turbo.json Add Turbo task config for docs build outputs/inputs.
README.md Point top-level README links at the published docs site.
pnpm-workspace.yaml Add docs workspace and docs/tooling catalogs.
pnpm-lock.yaml Lockfile updates for VitePress/TypeDoc/theme deps.
packages/entity/README.md Update package README to reference published docs routes.
knip.json Include docs workspace in knip projects/ignored deps.
docs/typedoc.json TypeDoc config for generating API docs into docs/api/entity.
docs/tutorial/getting-started.md New tutorial page introducing the library end-to-end.
docs/reference/types.md New reference page for helper types and seal names.
docs/reference/schemas.md New reference page documenting schema statics and behavior.
docs/reference/errors.md New reference page explaining error channels and InvalidEntity.
docs/reference/entry-points.md New reference page for factory/make/update/toJSON/equals.
docs/reference/declaration.md New reference page for Entity declaration and options.
docs/reference.md Remove old monolithic reference page (split into sections).
docs/public/logo.svg Add docs favicon/logo asset.
docs/public/icons/seal.svg Add home-page feature icon (seal).
docs/public/icons/schemas.svg Add home-page feature icon (schemas).
docs/public/icons/result.svg Add home-page feature icon (result).
docs/public/icons/nest.svg Add home-page feature icon (nesting).
docs/package.json New docs workspace package with VitePress/TypeDoc scripts.
docs/index.md New VitePress home page content and hero/features.
docs/how-to/test-domain-logic.md Add VitePress frontmatter for how-to page.
docs/how-to/persist-and-rehydrate.md Add VitePress frontmatter for how-to page.
docs/how-to/model-an-aggregate.md Add frontmatter and update links to new routes.
docs/how-to/http-contract.md Add VitePress frontmatter for how-to page.
docs/explanation/why-entity.md New explanation page (intro + core design rule).
docs/explanation/tags-and-identity.md New explanation page for _tag and discriminants.
docs/explanation/sealed-construction.md New explanation page for the seal and no subclassing.
docs/explanation/peer-dependencies.md New explanation page for peer dependency rationale.
docs/explanation/no-io.md New explanation page for generator-based creation.
docs/explanation/immutability.md New explanation page for deep immutability semantics.
docs/explanation/errors-are-values.md New explanation page for error vs defect boundary.
docs/explanation/computed-fields.md New explanation page for recomputation rationale.
docs/explanation.md Remove old monolithic explanation page (split into sections).
docs/api/index.md Add hand-written API landing page for generated TypeDoc output.
docs/.vitepress/theme/index.ts Configure site theme entrypoint and custom CSS.
docs/.vitepress/theme/custom.css Accent token + hero background glyph styling.
docs/.vitepress/config.ts VitePress site config (base, SEO metadata, sidebar, etc.).
CONTRIBUTING.md Document docs workspace build/dev commands and structure.
CLAUDE.md Update repo guidance to reflect docs workspace and TypeDoc setup.
.gitignore Ignore VitePress cache/dist and generated TypeDoc output.
.github/workflows/deploy-docs.yml New GitHub Pages deploy workflow for docs site.
.github/actions/setup/action.yml Composite action to set up Node/pnpm/cache/install.
.changeset/gentle-hoops-repeat.md Changeset noting README link updates (no code change).
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (3)

docs/tutorial/getting-started.md:155

  • report is not defined in this runnable tutorial example, which will cause the snippet to fail to type-check/run. Adding a minimal report implementation keeps the focus on the defect channel example.
    docs/tutorial/getting-started.md:139
  • This snippet references id, slug, name, and createdAt, which are undefined. Using values already in scope (like org.toJSON()) avoids unrelated name-resolution errors while still demonstrating that new Organization(...) does not compile.
    docs/tutorial/getting-started.md:259
  • This snippet references db (undefined in the tutorial) and uses top-level await. Switching to a simple console.log keeps the example runnable while still demonstrating the toJSON() projection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/tutorial/getting-started.md Outdated
updated it into a new instance, and projected it to the shape you would store or
respond with.

Everything here runs. Paste it into a `.ts` file and follow along.
Comment thread docs/tutorial/getting-started.md Outdated
`pnpm audit --audit-level=high` failed on GHSA-fx2h-pf6j-xcff, plus three
moderates on the same line, all reaching the tree through
docs > vitepress > vite. vitepress 1.6.x pins `vite ^5.4.14` and the 5.x line
has no patched release, so lift any pre-6.4.3 vite to 6.4.3 — the same override
unthrown carries, for the same advisory. That drags esbuild to a patched
0.25.x with it.

pnpm dedupes vitest's vite (previously 8.2.0) onto that 6.4.3 rather than
keeping a second copy. Measured and accepted: vitest 4.1.10 declares
`vite: "^6.0.0 || ^7.0.0 || ^8.0.0"`, so 6.4.3 is inside its supported range,
and all 145 tests pass on it. Path-scoped selectors were tried first and
produce the byte-identical tree — the dedupe is resolution, not the selector —
so the simpler form is kept, with the reasoning inline.

The tutorial claimed "everything here runs" while its snippets referenced
undefined helpers (`other`, `report`, `db`) that would bury the error each
example is about under unrelated name-resolution noise. The claim is now
accurate about what the page is — cumulative snippets, two of which are meant
not to compile — and the placeholders are replaced with values already in
scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@btravers

btravers commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 192d9cb addressing the CI failure and the review.

CI: Security Audit

pnpm audit --audit-level=high failed on GHSA-fx2h-pf6j-xcff (High, vite server.fs.deny bypass), plus three moderates on the same line — all four introduced by this PR via docs > vitepress > vite. vitepress 1.6.x pins vite ^5.4.14 and the 5.x line has no patched release, so the fix is the same override unthrown already carries for this advisory: lift any pre-6.4.3 vite to 6.4.3. That drags esbuild to a patched 0.25.x with it. pnpm audit --audit-level=high is now clean.

One consequence worth your call: pnpm dedupes vitest's vite onto that 6.4.3 rather than keeping a second copy, so the test runner's bundler moves 8.2.0 → 6.4.3. vitest 4.1.10 declares vite: "^6.0.0 || ^7.0.0 || ^8.0.0", so this is inside its supported range, and all 145 tests pass on it.

I tried path-scoped selectors (vitepress>vite) first to keep vitest on 8.x, and they produce the byte-identical tree — the dedupe is resolution, not the selector. The only way to actually split them is an inline vite devDependency on the library package for a purely transitive concern, which I judged not worth it. Reasoning is inline in pnpm-workspace.yaml; say the word if you'd rather pin.

Copilot review

Both comments were fair and are fixed.

"Everything here runs" overclaimed. It did — other, report and db were undefined, and each would have buried the error its example is actually about under unrelated name-resolution noise. The intro now says what the page truthfully is: cumulative snippets, two of which are meant not to compile.

Undefined identifiers. Replaced with values already in scope rather than adding stub definitions, so each snippet still shows exactly one thing:

Was Now
org.name = other org.name = "Other" as z.infer<typeof DisplayName>
new Organization({ id, slug, name, createdAt }) new Organization(org.toJSON())
defect: (cause) => report(cause) defect: (cause) => { console.error(cause); return "bug"; }
await db.insert("organizations", …) console.log(renamed.toJSON()) — also drops the top-level await

The three suppressed comments pointed at these same lines and are covered by the same changes.

Full gate re-run green: format --check, lint, audit, typecheck, test (145), knip, build. Site rebuilt; the #_6-handle-failure-as-a-value anchor the tip links to still resolves.

@btravers
btravers merged commit 38609a8 into main Aug 7, 2026
13 checks passed
@btravers
btravers deleted the docs/vitepress-site branch August 7, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants