Skip to content

Publish prep: the six runtime packages at 0.1.0 - #1

Merged
softov merged 4 commits into
mainfrom
release/0.1.0
Aug 24, 2026
Merged

Publish prep: the six runtime packages at 0.1.0#1
softov merged 4 commits into
mainfrom
release/0.1.0

Conversation

@softov

@softov softov commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Everything needed before the first npm publish. The codebase itself needed no work — build, typecheck, lint, docs and 1692 tests were green before this branch, with zero TODO/FIXME in packages/*/src. What was missing was publish mechanics.

One real bug

@textui/core declared an ./hooks export subpath pointing at dist/hooks/, which tsc never emits — hooks live in runtime/hooks.ts and are already re-exported from the root. Nothing in the repo imported that subpath, which is exactly why every check stayed green. It would have been ERR_MODULE_NOT_FOUND for the first consumer who tried it.

scripts/check-exports.mjs now runs in CI on every PR so the next one fails a review instead of a release. It was verified against the bug it exists for: reintroducing ./hooks makes it exit 1 and name both targets.

What ships

Six, in dependency order — pnpm publish -r works this out itself:

@textui/core
  -> @textui/widgets, @textui/terminal
       -> textui, @textui/testing, @textui/cli

@textui/documents, @textui/textide and @textui/textide-git are marked private. They build in CI and stay in the repo, but an IDE should not be tied to the runtime's release cadence. Being private is the only thing holding them back — a publish-time filter you have to remember is one that gets forgotten.

Also in here

  • LICENSE in all nine tarballs. "license": "MIT" is a label, not the text, and npm only picks up a LICENSE in the package's own directory.
  • Release machineryRELEASING.md, CHANGELOG.md, and a tag-triggered release.yml that reruns the full gate, checks the tag against the manifests, packs every tarball, then publishes with provenance. workflow_dispatch runs all of it and publishes nothing, so the first real tag is not also the first rehearsal.
  • README split — the README is now for someone arriving from npm (install line, the one idea, packages, pictures); building the workspace, the playgrounds, the docs site and the erasable-syntax argument move to DEVELOPER.md. That argument's count had drifted to fourteen across twelve files and its tsconfig flag is not actually set, so it now reads as a direction rather than a property.
  • Two doc errors fixed — the documents guide put the JSON adapter in @textui/core/adapters (a deliberately empty placeholder); it is in @textui/documents. Six package READMEs linked to siblings as ../core, which resolves here and 404s on npmjs.com.

Still needed before a tag

The @textui scope is reserved, but nothing can publish yet: there is no NPM_TOKEN repository secret, and npm is not authenticated on the machine this was prepared on. RELEASING.md covers it — it needs an automation token (a classic token with 2FA on publish cannot be used unattended).

Gate on this branch: build, typecheck, lint, docs, exports guard, version check and all 1692 tests pass.

softov added 4 commits August 24, 2026 16:25
The export map pointed `./hooks` at `dist/hooks/`, which tsc has no reason to
emit - the hooks live in `runtime/hooks.ts` and are already re-exported from
the root. Nothing in the repository imported the subpath, so it compiled clean
and would have been ERR_MODULE_NOT_FOUND for the first consumer who tried it.

A type checker cannot catch that, so `check-exports.mjs` does: every exports
and bin target has to exist in the built tree and be covered by files[], and
every publishable package needs a README and a LICENSE. It runs in CI on every
pull request, beside `check-version.mjs`, which the release workflow uses to
hold the tag and the manifests to the same number.
…t all

`"license": "MIT"` in a manifest is a label, not the text, and npm only picks up
a LICENSE sitting in the package's own directory - so nine packages declared a
licence they did not carry.

documents, textide and textide-git are marked private. They build in CI and
they are in the repository, but their surface has not settled and an IDE is not
something to tie to the runtime's release cadence. Being private is what holds
them back, and deliberately the only thing that does: a filter you have to
remember at publish time is a filter that gets forgotten.
`pnpm publish -r` already walks the dependency order and rewrites workspace:^,
so the workflow's job is to refuse rather than to sequence: the same build,
typecheck, lint and test CI runs, then the exports guard, then a check that the
tag and the manifests agree. It packs every tarball before it publishes any,
and signs them with provenance.

workflow_dispatch runs all of that and publishes nothing, so the first real tag
is not also the first rehearsal.
Someone arriving from npm wants the install line, the one idea, the packages
and a picture. Building the workspace, running the playgrounds, serving the
Jekyll site and cutting a release are all real, and none of them are that -
they move to DEVELOPER.md, along with the erasable-syntax argument, whose count
had drifted to fourteen across twelve files and whose tsconfig flag is not
actually set. The README keeps the claim it can make: no dependencies.

Two things that were simply wrong: the documents guide put the JSON adapter in
`@textui/core/adapters`, which is a deliberately empty placeholder that says so
itself - it is in `@textui/documents`. And six package READMEs linked to
siblings as `../core`, which resolves in the repository and 404s on npmjs.com.
@softov
softov merged commit a2f2e7a into main Aug 24, 2026
3 checks passed
@softov
softov deleted the release/0.1.0 branch August 24, 2026 20:32
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.

1 participant