Version Packages#104
Merged
Merged
Conversation
c66d29e to
9580ed9
Compare
9580ed9 to
7339119
Compare
KayleeWilliams
added a commit
that referenced
this pull request
Jul 7, 2026
* Revert "Version Packages (#104)" This reverts commit 92b9455. * ci(release): skip git hooks in the changesets action commit The changesets action commits 'Version Packages' via git-cli on the runner, which fires the husky pre-commit hook. The hook's test suite needs a built leadtype dist (the repo-docs lint test typechecks snippets against the package), and the Release job never builds one, so every Release run since snippet typechecking landed has failed inside the hook — leaving the Version Packages PR stale and blocking publish. CI already builds and runs the full suite on the PR, so set HUSKY=0 on the changesets step.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
leadtype@0.4.0
Minor Changes
e43820f: Batch Git frontmatter enrichment during
convertAllMdx(closes Investigate batching git frontmatter enrichment during conversion #108).When
enrichFrontmatterFromGitis enabled, batch conversion now reads Git history once for the docs tree and maps results back to each converted file instead of spawninggit logper file. A 120-file synthetic docs benchmark measured the Git metadata read dropping from ~2.36s of per-file process spawning to ~12ms for the batched read; end-to-end conversion added ~27ms over no enrichment.The enrichment remains best-effort for shallow clones, missing Git, and untracked files.
lastModifiedstill comes from the latest file commit, whilelastAuthornow falls back to the latest non-bot author when the newest commit was authored by automation.ec301dc: Add generated API catalog and homepage discovery Link helpers for agent-readable sites.
generateandgenerateAgentArtifacts()now emit/.well-known/api-catalogalongside robots and sitemap artifacts, route handlers can serve it dynamically, andleadtype/llm/readabilityexports helpers for RFC 8288Linkheaders that advertise the catalog, service docs, service description, and sitemap. Robots output also includes scanner-friendly AI crawler aliases and renders Content-Signals inai-train, search, ai-inputorder.3f26072: Use Satteri and the native markdown pipeline for agent-facing markdown conversion.
convertAllMdx,convertMdxFile,convertMdxToMarkdown, andleadtype generatenow parse MDX through Satteri and run native markdown transforms/stringification for agent-facing output.The legacy agent-side Remark conversion path has been removed. This removes
markdownEngine, theleadtype/remarkcompatibility export, and legacy aliases such asdefaultRemarkPlugins,legacyDefaultMarkdownTransforms, andbuiltinFlattenerPlugins. Source-MDX bundler APIs underleadtype/mdxandleadtype/mdx/sourceremain intact.a0afb74: Add an opt-in
pruneoption toconvertAllMdxthat removes orphaned.mdoutputs when a source page is deleted or renamed.
Previously a renamed page left its old
.mdbehind inoutDir— a live URLwith stale content that leaked into sitemaps, link checks, and search
indexing — and every consumer had to hand-roll the same garbage-collection
step. With
prune: true,convertAllMdxdeletes any.mdunderoutDirthat the current source set did not produce, then removes directories the
deletions emptied.
Guardrails:
.mdfiles are candidates; other files sharingoutDirare nevertouched, and symlinks are never followed.
srcDirresolves to zero pages, so a partial or misconfigured run nevermass-deletes output.
pruneKeepglobs (relative tooutDir) exempt.mdfiles written byother tools, e.g.
pruneKeep: ["sitemap.md", "mirrors/**"]. Nothing isexempted implicitly.
outDirlock asleadtype generate(reentrant when generate itself is the caller;LEADTYPE_NO_LOCK=1opts out), so a prune cannot delete output aconcurrent run just wrote.
b7a8c89: Add a
generatedAtoption to the agent artifact generators so manifests andtimestamp fallbacks can be reproduced byte-for-byte across deterministic builds.
1406340: Make
leadtype lintconfig-aware, so a bareleadtype lintvalidates thesame source tree — with the same routing rules — that
generatebuilds.--src, lint findsleadtype.config.*atthe project root or
docs.config.*in./docs/./content, exactly likegenerate, and lints that tree. Flags still override everything. A config
that fails to load reports a lint failure instead of crashing.
mountsapplied, and links under every mount prefix (e.g./changelog/v1)are validated like
/docs/...links — including catching stale/docs/...paths to pages that moved under a mount. Links under generated trees (the
OpenAPI
outputprefix) are assumed valid, since those routes only existafter
leadtype generate.config-linkrule): curatednavigationentries matching no page andllms.sectionslinks to missingroutes are errors; feed
source.urlPrefixvalues matching no pages andredirects.removedpaths that are live again are warnings. Previouslythese bypassed lint and only surfaced when generate blew up.
lintblock in the docs config:lint.ignorereplaces the defaultignore globs,
lint.unknownFieldSeveritysets the unknown-field default,and
lint.rulesremaps any rule's severity ("off"/"warn"/"error") across the CLI and thelintDocs()API (newrules,mounts,and
assumeValidLinkPrefixesoptions).1a50f09: Expand
leadtype lint's internal link coverage (closes the gaps tracked inExpand internal link linting coverage #86):
./sibling,../guides/x, extension optional) resolveagainst their source file and validate like absolute links; links that
climb out of the docs tree are errors.
invalid-anchorrule): same-page#fragmentlinks and fragments on cross-page docs links must match a heading anchor on
the target page. Anchors are extracted from the rendered markdown with the
same slugger and duplicate handling that builds the site TOC — includes
expanded — so lint and the rendered site cannot disagree. (Running this on
leadtype's own docs immediately found three anchors that had been silently
broken on the live site.)
invalid-linkwhose target matches a lockfile redirect reports"moved to
<new path>— update the link" instead of a bare missing-routeerror.
fe383ac: Add parse-level code snippet linting (
snippet:parse, the first tier ofLint code snippets #93): every fenced code block with a known language must parse — TS/TSX/JS
via the TypeScript parser (skipped when the optional
typescriptpeerdependency isn't installed), JSON and YAML via real parsers.
Docs snippets are deliberately fragmentary, so the checker is
fragment-tolerant before it reports: bare API signatures,
key: valueconfig excerpts, object- and type-shape blocks, sibling JSX examples, and
...ellipsis lines all parse without annotation, as do JSON comments,trailing commas, and multi-document YAML. Anything else can be marked
deliberate with a twoslash-style
// @noErrorsline — the same directivethe upcoming typecheck tier honors.
Tuned on leadtype's own 51-page docs corpus: zero annotations needed, and
the only findings were real bugs (a JSX component in a
tsfence andconfig excerpts that couldn't parse standalone).
ece9d1f: Add opt-in TypeScript snippet typechecking (
snippet:types) — the flagshiptier of code-snippet linting: with
lint: { snippets: { typecheck: true } }in the docs config, module-shaped
ts/tsxsnippets are assembled intovirtual modules and typechecked against your project's
tsconfig.jsonandreal
node_modules. When a package API changes, every doc example stillcalling the old API fails lint — docs that can't rot.
// @filename: name.tsbuilds multi-file examples(parts can import each other),
// @checkopts a fragment in,// @noErrorsopts anything out, and// ---cut---hides setup linesfrom rendered output while they still typecheck. A new default markdown
transform strips all directives from generated mirrors and converted
output, so the authoring convention never reaches readers.
import/exportare checked by default (the copy-pasteable ones), imports of packages your
project doesn't install degrade to
anyinstead of failing, and JSXenvironment gaps (no React installed) are tolerated — strictness applies
to everything that resolves, most importantly the documented package
itself.
regardless of snippet count.
4738c1c: Add native OpenAPI page generation for API reference docs. OpenAPI 3.x specs generate MDX operation pages with endpoint, auth, parameter, request/response, and code-sample components that render through your docs UI and flatten into agent-readable markdown (llms.txt, search, package docs bundles).
createDocsSource()/fumadocsSource()acceptopenapiconfig directly, read authored docs live fromcontentDir, and overlay generated pages in a temp directory withcleanup()support;stageOpenApiDocs()keeps full-copy staging for custom pipelines.results[].title), and cURL/fetch samples with auth headers and real payloads;x-codeSamplesoverrides are honored.leadtype/openapiplusApi*renderer prop types are part of the package surface. The dependency-freeleadtype/mdx/openapisubpath exportsflattenApiSchemaRows()so custom renderers derive the same nested property rows (results[].title) as the built-in markdown flatteners.$reftargets time out after 30 seconds, and generated OpenAPI pages now fail loudly instead of overwriting pre-existing docs files.fc714e4: Add opt-in redirect tracking for renamed and deleted docs pages, so old URLs
stop 404ing in search engines and agent indexes.
Enable it with a
redirectsblock indocs.config.ts.leadtype generatethen maintains a committed lockfile (
paths.lock.jsonnext to the docssources) recording every published path with a content hash, and emits
<out>/docs/redirects.json:its content hash reappears at a new path gets a permanent 308 redirect
with zero authoring. Hashes exclude frontmatter, so git-enrichment churn
doesn't defeat the match, and ambiguous matches are never guessed.
with the fix: add
redirectFrom: [<old path>]frontmatter to thesuccessor page, or acknowledge intentional deletions under
redirects.removedto serve 410 Gone.collapse to the final target, entries whose target is later removed
degrade to 410, and entries whose path comes back alive are dropped.
leadtype/redirectsentry point exportsresolveRedirectand the pure computation primitives for serving redirects in any
framework's catch-all (no Node built-ins, so it links in Cloudflare
Workers / Vercel Edge); generate-time lockfile IO lives under
leadtype/redirects/node.createAgentMarkdownResponseaccepts theentries directly and answers agent-shaped requests for renamed pages —
including
.mdmirrors, with index-route targets resolved to their realindex.mdmirror path — with the 308/410, while browser requests fallthrough to the host app's routing.
redirectsalso enables conversion pruning, since renamedetection requires stale mirrors of renamed sources to be
garbage-collected from the output set.
--include/--exclude) skip redirect tracking andpruning with a warning — a partial page set would make every excluded page
look deleted.
redirectFromis now part of the default frontmatter lint schema.b5219fd: Add
--watchand incremental builds toleadtype generate.leadtype generateis now incremental by default: each converted file's inputs — the MDX source, its<include>targets, the TypeScript files its type tables extract from, and its git enrichment — are content-hashed into a manifest undernode_modules/.cache/leadtype/, and unchanged files are skipped on repeat runs. Outputs whose source file was deleted are pruned.--forcebypasses the cache; the cache also invalidates automatically on leadtype version, docs-config, or flag changes.leadtype generate --watch(or-w) runs the pipeline, then watches the docs source directories and config file and re-runs on change (debounced). With the cache, a one-file edit rebuilds one file.Library API:
convertAllMdxaccepts a new optionalcacheoption, and conversion reports every extra file it reads (include targets via the existing_compiler.addDependencyprotocol, now also type-table TypeScript sources — exposed asTypeTableOptions.onDependency).Patch Changes
4e743a6: Cache repeated
<include>/<import>resolution within a conversion run.remarkIncludenow accepts an optional include-resolution cache andconvertAllMdx()creates one cache per batch run, so pages that reuse the samepartial share the raw file read and parsed markdown AST. Cache keys are scoped
to absolute resolved paths and parser identity, while section anchors such as
file.mdx#setupstill extract independently from cloned ASTs.The new
createIncludeResolutionCache()helper exposes lightweight cache statsfor instrumentation. Current docs and c15t fixtures do not contain repeated
real include nodes, but a synthetic 200-page repeated-include benchmark showed
one raw read, one markdown parse, and roughly a 5.9x speedup in include
expansion time.
d569171: Make generation safe to invoke concurrently against a shared
outDir.Parallel task graphs (lint, typecheck, and build each depending on "docs are
generated") used to race on the shared output directory, causing intermittent
partial reads, ENOENT on files another run had just replaced, and half-written
artifacts.
docs/*.md,llms.txt,llms-full.txt,search index, sitemaps, robots, feeds, MCP card, NLWeb, skills, sync
manifests) is now written to a temp sibling and atomically renamed into
place, so concurrent readers see the old content or the new content — never
a truncated file.
markdown mirrors now write the new files first and prune stale ones after,
instead of
rm -rf-ing a live directory before rebuilding it.leadtype generateruns are single-flight per output directory via across-process lock stored under the system temp dir (keyed by the resolved
--outpath). Concurrent invocations wait for the in-flight run. Abandonedlocks recover fast: interrupted runs (SIGINT/SIGTERM) release on the way
out, hard-killed runs are reclaimed as soon as their recorded pid is gone,
and unidentifiable locks are reclaimed after 10 minutes. Waiting runs fail
loudly after 15 minutes instead of hanging CI (
LEADTYPE_LOCK_TIMEOUT_MSoverrides). Set
LEADTYPE_NO_LOCK=1to opt out. Temp files leaked by ahard-killed run are swept at the start of the next locked run.
07ccef9: Sort
manifest.pagesfromgenerateAgentReadabilityArtifactsin navigationorder instead of alphabetical
urlPathorder.Navigation order (groups depth-first, then pages within each group) is the
authored reading order, which is what agent/LLM consumers of the manifest want.
Pages not present in the navigation are appended sorted by
urlPath, so theoutput stays fully deterministic.
sitemap.xmlis rendered from the same listand now shares the navigation order;
sitemap.mdalready followed it.generateLLMFullContextFilesnow applies the same ordering in legacygroupsmode (it previously only reordered under curated
nav), sollms-full.txtstays in sync with the manifest in both modes. The bring-your-own-pages
generateAgentArtifactsentry point is unchanged — there the inputpagesorder is the authored order.
Fixes generateAgentReadabilityArtifacts: sort manifest pages in navigation order #115.