chore(release): unblock the 0.1.0 publish pipeline - #51
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Gets the publish pipeline into a state where it can actually run. The headline is that the release workflow could not have succeeded as it stood — see the first item.
The blocker
.changeset/config.jsonstill listedignore: ["intentface"], the registry package deleted back in #44. Changesets treats anignoreentry that matches no workspace package as a fatalValidationError, sochangeset status,changeset versionandchangeset publishall aborted before doing anything:Removed the entry.
changeset statusnow resolves@intentface/chatatminor, and.changeset/README.mdno longer refers to the deleted registry CLI either.Changeset text
initial-release.mdadvertised a surface that no longer exists:StepQueue(removed in #30),ArtifactCard/ArtifactsPanel, and "styled components ship separately via the shadcn-compatible registry" (the registry was deleted in #44). Since this text becomes the published 0.1.0 changelog entry, it's rewritten to describe the eleven entry points that actually ship.Workflows
Both were
workflow_dispatch-only, commented "paused during initial development". Restoredpush: [main]+pull_requestonci.ymlandpush: [main]onrelease.yml.Because this is the PR that turns CI on, it also has to leave
maingreen — andmaincurrently has twobiome checkfailures, both pre-existing and unrelated to any of the above:packages/chat/tests/a11y/harness.a11y.test.tsx— the negative-control fixture tripsuseValidAriaValueson its deliberatearia-label="". Extended the ignore comment. (Same one-line fix as in feat(composer)!: remove TipTap engine and batch pre-1.0 renames #50; identical text, so the two merge cleanly.)components/chat.tsx— an unsorted import and an over-wrapped import block failingorganizeImports. Applied Biome's own fix; reordering only, no semantic change.Manifest
Added
authorandbugstopackages/chat/package.json. Deliberately did not addengines: the package targets browsers, and a Node floor there produces install warnings for consumers it doesn't actually constrain.Verified
A real
npm pack(not--dry-run, so theprepack/postpackexport swap genuinely executes):exportspoint at./dist/src/*, andpublishConfig.exportsis consumed — the swap worksdist/,LICENSE,README.mdand nothing else — no source, tests, or scripts leakedpostpackrestored the working tree to the./srcdev exports, leaving nopackage.json.prepack-bakchangeset versionin a throwaway clone: bumps 0.0.0 -> 0.1.0 and generates a correctly attributedCHANGELOG.md. Worth knowing that@changesets/changelog-githubhard-fails without a validGITHUB_TOKEN(it escapes cleanly and changes nothing) —release.ymlsets it at step level so both the action and the spawnedbunx changeset versioninherit it, which is correct.Also green: 184 tests,
tsc --noEmit,biome check, package build +publint.Still needs you — not doable from here
@intentface/chat, pointing at this repo andrelease.yml. This can only be done after 0.1.0 exists on the registry — npm requires the package to already be published, both via the web UI and vianpm trust. So 0.1.0 gets published manually; every release after that comes from CI with no credentials.No
NPM_TOKENis needed —release.ymlnow authenticates via OIDC, so there is no long-lived secret to store or rotate. The@intentfaceorg already exists.Heads-up: npm/cli#8976 reports E404 on scoped packages published via
changeset publishfromchangesets/actionunder OIDC — open since February 2026. That is this exact shape, so treat the first CI-driven release as unproven until it succeeds once.Ordering
Merges cleanly with #50 (verified with
git merge-tree). Either order works; both branch frommainand target it independently.Update: two release-blocking bugs in the built artifact
After the pipeline work above, I packed the tarball and installed it into a throwaway Next 16 app with no
transpilePackages, so it resolveddist/the way a real consumer does. That found two bugs that every green check we had —publint,tsc --noEmit, 184 tests, the app build — was structurally incapable of catching, because nothing in this repo has ever consumed the built output. The app compiles./srcviatranspilePackages.1. Every compound component shipped as
unknownbunup's default declaration emit uses TypeScript's isolated-declarations mode, which cannot infer the type of an
Object.assign(Root, {...})compound. It warnedTS9010and emitted:All eight compound components —
Thread,Composer,Message,Steps,Reasoning,Chip,Attachments,AskUser— plus several hooks and utilities were erased. The entire public API was unusable from TypeScript:JSX element type 'Thread' does not have any construct or call signatures.Those
TS9010warnings were visible in the build all along, onmaintoo, and I dismissed them earlier in this work as non-blocking because.d.tsfiles were still produced. That was wrong — they were produced with the types erased.Fixed with
dts: { inferTypes: true }, which routes declaration emit through tsc.reasoning.d.tswent from 568 B to 5.80 KB, which is the measure of how much was being dropped.publintpassed before and after: it validates packaging, not type correctness.2. The dev JSX runtime was bundled
dist/importedjsxDEVfromreact/jsx-dev-runtime— 68 call sites, zero uses of the productionreact/jsx-runtime. Any consumer's production build throws:Bun's transpiler picks the runtime from the build process's
NODE_ENV, and bunup was running with it unset. Thejsx: { development: false }option looks like the declarative fix, but bunup 0.16.32 ignores it — verified, still 68jsxDEVcalls — so the build script pinsNODE_ENV=productioninstead.prepackalso ran barebunup, so it would have kept emitting the dev runtime even afterbuildwas fixed — andprepackis what produces the published tarball. It now callsbun run build, so there's one source of truth.Verified against the packed tarball
With
NODE_ENVexplicitly unset in the shell,npm pack→ install →next build:react/jsx-runtimeimports, zerojsxDEVdeclare const … : unknownin any.d.ts"use client"page using the compounds, their sub-components,useComposer/useReasoning/useThread, and event handlers — builds and prerenders/types,/message-utils,/chip-markdown— builds and prerenders@floating-ui/domandnanoidbeyond ReactAlso documented: compound sub-components and RSC
While isolating the above I hit a third thing, which is a genuine React constraint rather than a bug. Reaching a sub-component from a server component fails at runtime:
A server component importing a client module gets a proxy of that module's named exports; it cannot read properties off an exported value, and the sub-components live on the
Composerobject. Radix-styleimport * as Dialogsidesteps this because the namespace's properties are named exports — a compound object can't. Bare<AskUser />works;<AskUser.Header />does not.This needs no code change — chat UI is interactive, so consumers will be in client components anyway — but the failure mode is cryptic enough to deserve documentation, so the README now has a React Server Components section stating the rule and showing both shapes.