Skip to content

Merge @stacksjs/ts-css into this repo as packages/toolkit - #27

Open
glennmichael123 wants to merge 41 commits into
mainfrom
merge/ts-css-toolkit
Open

Merge @stacksjs/ts-css into this repo as packages/toolkit#27
glennmichael123 wants to merge 41 commits into
mainfrom
merge/ts-css-toolkit

Conversation

@glennmichael123

Copy link
Copy Markdown
Member

Chris asked that we "merge" @stacksjs/ts-css and this project, since the rename collided with a name that was already his. This does that.

They turn out to be opposite halves of one pipeline, so this is mostly packaging — the toolkit reads CSS (parse / what / select / optimize, a TS rewrite of the css-tree/css-select/csso stack), this framework writes it. Overlap is near zero: parser.ts sounds like a duplicate but parses class names, not CSS.

One repo, two published packages. The toolkit keeps its name and its 0.1.x line — it has real dependents and is already in our own dependency tree — and the framework now consumes it.

What's here

packages/toolkit @stacksjs/ts-css @ 0.1.4, grafted with all 36 commits of history
packages/ts-css the framework — name still TBD, currently @ts-css/core
packages/vscode scoped alongside

Subtree merge, not a squashed import. The merge commit has two real parents, so stacksjs/ts-css history is preserved and browsable.

Config collision resolved. Both packages called loadConfig({ name: 'css' }) through bunfig, so any project using both handed the same css.config.ts to two incompatible schemas. The toolkit moves to ts-css.config.ts — matching its own package and bin name — as the cheaper side: two keys, one docs mention, nothing in tests. The framework keeps css.config.ts, which its docs and cssx init already emit.

The one place this buys real code. The framework's minifier was eight chained regexes that couldn't tell a space inside a string or url() from a space between tokens. It now calls the toolkit's AST-based minifyBlock. Both are synchronous, so toCSS() is unchanged.

Two incidental fixes. The toolkit's tokenizer tripped this repo's pickier config on a discarded resize temporary (its two siblings already had the disable comment), and buddy-bot was pointed at stacksjs/ts-css — a different project — so its dependency PRs were being opened against the wrong repo.

Things that resolved themselves

  • The circular dependency is gone. @stacksjs/ts-css now resolves to workspace:packages/toolkit, so @stacksjs/ts-svg's ^0.1.0 is satisfied in-repo rather than pulling an older, different version of the same name.
  • No build ordering needed. The toolkit's export map points at ./dist/optimize/index.js and dist/ is gitignored, so this looked like it would need the toolkit built first. Bun bundles it from source instead — the optimizer is inlined into the framework's chunk with no external reference, exactly as bunfig already is. CI needs no sequencing change.

Verification

2003 tests pass, 0 fail across 56 files (both suites in one run), typecheck clean, lint 0 errors. The minifier swap was checked end-to-end rather than by test count alone: p-4 m-2.p-4{padding:1rem}.m-2{margin:0.5rem} through the toolkit's AST path.

Still open — not in this PR

  1. What does the framework publish as? It no longer needs the contested name. @stacksjs/cssx and @stacksjs/crosswind are free; @cwcss/ts-css and @cwcss/core are free in a scope we already own and where the token demonstrably works (@cwcss/crosswind@0.2.19 shipped through it).
  2. Which org holds the merged repo?

No tag has moved and nothing has been published. When it's time, the toolkit should publish first — @stacksjs/ts-css@0.1.5 is an update to an existing package, so it needs no new npm permissions and proves the merged pipeline before the framework's first publish tests token creation rights. That's what the last three release runs failed on: 404 Not Found, which is npm's response when a token can't create a package.

🤖 Generated with Claude Code

https://claude.ai/code/session_01F1vnJJiE1mSHcBStFJarNL

chrisbbreuer and others added 30 commits April 28, 2026 13:21
chore: wip

chore: wip
Drop the redundant 'bun --bun run changelog:generate &&' prefix from
release scripts; bumpx already calls @stacksjs/logsmith internally
with the proper from/to tag range, so the standalone pre-step was
prepending a duplicate section to CHANGELOG.md on every release.

Refs: stacksjs/rpx#2260
better-dx / direct buddy-bot dep now resolves the just-published
buddy-bot@0.9.20 (flatten of gh-audit into the main package).
better-dx's logsmith peer dep now resolves @stacksjs/logsmith@0.2.3
(h2 section headings + blank-line preservation in changelog output).
better-dx's pickier peer dep now resolves to 0.1.33.
better-dx's pickier peer dep now resolves to 0.1.35.
So pantry provisions the toolchain (bun + bunx) from a single declared
source. ^1.3.14 is bun's newest public release.
chrisbbreuer and others added 7 commits August 18, 2026 20:33
Every consumer downloads this dist and none of them reads it. Unminified it
was roughly a quarter whitespace.

Verified rather than assumed: each entry in the export map was imported before
and after the change and its export list compared, so a build that quietly
dropped or renamed part of the surface would have failed here instead of in
someone else's project.
Every byte here is downloaded by every consumer and read by none of them.
Verified by importing each export-map entry before and after and comparing
export lists, with dist deleted first so stale output could not flatter
either side.
The manifest declared a command whose file the build never produced, so
`dist/bin/` did not exist in any published version. Every install logged a
failed bin link and the command was simply unavailable — declared, resolvable
by name, and missing.
The unscoped `ts-css` name collides with @stacksjs/ts-css on npm, and the
last three release runs failed with 404 because the token could not create
a new unscoped package. Scoping sidesteps both.

The final scope is still open — this commit moves the tree off the
unpublishable name so the merge work can proceed on top of it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1vnJJiE1mSHcBStFJarNL
glennmichael123 and others added 4 commits September 1, 2026 22:31
Grafts the CSS toolkit (parse/what/select/optimize) into this monorepo via
a subtree merge, so both projects keep their full commit history rather
than arriving as a squashed import.

The two are complementary halves of one pipeline: the toolkit reads CSS,
this framework writes it. The only real overlap is minification, which the
toolkit does properly.

The imported history is rewritten to drop bin/ts-css, a 60MB compiled CLI
the upstream repo tracks in three versions. Keeping it would have added
182MB to every clone of this repo, forever. bin/cli.ts — the source the
binary is built from — is untouched, and all 36 commits are preserved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1vnJJiE1mSHcBStFJarNL
Two packages both called loadConfig({ name: 'css' }) through bunfig, so a
project using both would hand the same css.config.ts to two incompatible
schemas. The toolkit moves to ts-css.config.ts — matching its own package
and bin name — as the cheaper side: two keys, one docs mention, nothing in
tests. The framework keeps css.config.ts, which its docs and `cssx init`
already emit.

The framework's minifier was eight chained regexes that could not tell a
space inside a string or url() from a space between tokens. It now calls
the toolkit's AST-based minifyBlock, which is the one place this merge
buys real code. Both are synchronous, so toCSS() is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1vnJJiE1mSHcBStFJarNL
The toolkit's tokenizer tripped this repo's pickier config on a discarded
resize temporary; its two siblings already carried the disable comment.

buddy-bot was configured for stacksjs/ts-css — a different project — so
its dependency PRs were being opened against the wrong repository.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1vnJJiE1mSHcBStFJarNL
The framework imports @stacksjs/ts-css/optimize, whose export map points at
./dist/optimize/index.js. dist/ is gitignored, so on a clean checkout that
target does not exist yet.

Local Bun 1.3.14 papers over this by falling back to source when the export
target is missing; CI's Bun 1.4.0 does not, and the build failed with
"Could not resolve". A source-condition export is not an option either —
the toolkit publishes files: [README.md, dist], so src never ships.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1vnJJiE1mSHcBStFJarNL
@glennmichael123

Copy link
Copy Markdown
Member Author

Rebuilt the branch after a size problem surfaced in review.

The toolkit repo tracks its own compiled CLI. bin/ts-css is a 60MB binary, and upstream has three versions of it in history. A plain subtree merge brings all of them — the toolkit's commits are a real second parent, so their blobs come along regardless of what the merge tree looks like. That was 182MB added to every clone, forever.

The imported history is now rewritten with git filter-repo --invert-paths --path bin/ts-css before grafting:

  • All 36 commits preserved and still ancestors of HEAD — this is not a squashed import
  • bin/cli.ts, the source the binary is built from, is untouched
  • No blob over 5MB enters from the toolkit

The tradeoff: rewriting changes the imported commits' SHAs, so packages/toolkit history no longer matches stacksjs/ts-css upstream commit-for-commit. The messages, authors, dates and tree contents are identical.

Large blobs still reachable from this branch are all pre-existing crosswind history — packages/crosswind/bin/*, packages/headwind/bin/*, packages/ts-css/bin/crosswind — none from this merge. Those are what 70a5a2d left behind, and clearing them would be a separate rewrite of main.

Also added the ignore rules matching this repo's existing convention so nothing re-accumulates:

packages/toolkit/bin/ts-css
packages/toolkit/bin/ts-css-*
packages/toolkit/bin/*.zip

One real bug caught by CI, now fixed in 50026f8. The framework imports @stacksjs/ts-css/optimize, whose export map points at ./dist/optimize/index.js — and dist/ is gitignored, so on a clean checkout that target does not exist. Local Bun 1.3.14 papers over it by falling back to source; CI's Bun 1.4.0 does not, and the build failed with Could not resolve. A source-condition export was not an option either, since the toolkit publishes files: [README.md, dist]. The root build script now builds the toolkit first.

All four checks green on 50026f8.

🤖 Generated with Claude Code

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