build: bundle dspack-gen/core so the npm package is self-contained - #20
Conversation
…f-contained npm has only ds-mcp 0.2.0 while the README quickstart downloads the v0.4 example — which 0.2.0 hard-rejects. 0.3.0 was unpublishable as-is: its dspack-gen dependency is a git URL to a private-on-npm package, forcing every consumer install to clone GitHub and run a TypeScript build, and pulling runtime deps (@anthropic-ai/sdk, undici, dspack-emit) that the consumed zero-network core subpath never uses. dspack-gen (same pinned commit) moves to devDependencies as the build-time source of truth. `npm run bundle:core` (esbuild) compiles its dist/core into dist/vendor/dspack-gen-core.js — ajv external since ds-mcp depends on it directly — and the tools import that bundle via a type facade (src/vendor/dspack-gen-core.d.ts) that type-checks against the real dspack-gen types. The network-boundary test now also scans the shipped vendor bundle. Clean-room verified: tarball install has no dspack-gen in node_modules, tools/list shows 11 tools against the v0.4 example, get-generation-context and validate-ui return real results, smoke.sh green, 93/93 tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR makes the published @aestheticfunction/ds-mcp npm package self-contained by bundling the zero-network @aestheticfunction/dspack-gen/core runtime into dist/vendor, so consumers don’t need to install a private git dependency at runtime.
Changes:
- Moves
@aestheticfunction/dspack-genfromdependenciestodevDependenciesand adds an esbuild-drivenbundle:corestep to producedist/vendor/dspack-gen-core.js. - Switches tool implementations to import the vendored bundle via a relative specifier.
- Extends the network-boundary test and documents the build-time dependency arrangement in the README.
Reviewed changes
Copilot reviewed 5 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vendor/dspack-gen-core.d.ts | Adds a type facade for the vendored/bundled dspack-gen core module. |
| src/tools/validate-ui.ts | Updates imports to use the vendored dspack-gen core bundle. |
| src/tools/get-generation-context.ts | Updates imports to use the vendored dspack-gen core bundle. |
| src/tests/generation-tools.test.ts | Expands network-boundary scanning to include the shipped dist/vendor bundle. |
| README.md | Documents the new build-time bundling approach and rationale. |
| package.json | Adds bundle:core and wires it into build; moves dspack-gen to devDependencies; adds esbuild. |
| package-lock.json | Updates lockfile to reflect dependency changes and added esbuild. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * an LLM call, and the MCP host already is one. | ||
| */ | ||
| import { compileContext, type Contract } from '@aestheticfunction/dspack-gen/core'; | ||
| import { compileContext, type Contract } from '../vendor/dspack-gen-core.js'; |
There was a problem hiding this comment.
Fixed in 3c7e464 — header now names the bundled vendor entry (../vendor/dspack-gen-core.js) and points at the type facade.
| type Contract, | ||
| type LintReport, | ||
| } from '@aestheticfunction/dspack-gen/core'; | ||
| } from '../vendor/dspack-gen-core.js'; |
There was a problem hiding this comment.
Fixed in 3c7e464 — header now names the bundled vendor entry and the type facade.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why
npm serves only ds-mcp 0.2.0, while the GitHub README quickstart tells users to download the v0.4 example — which 0.2.0 hard-rejects (
Unsupported dspack version '0.4'). The unpublished 0.3.0 couldn't ship cleanly: its dspack-gen dependency is a git URL to a package that is private on npm, so every consumer install would clone GitHub and compile TypeScript viaprepare, and would pull runtime deps (@anthropic-ai/sdk,undici,dspack-emit) that the consumed zero-networkcoresubpath never uses.What
@aestheticfunction/dspack-gen(same pinned commitf651433) moves to devDependencies — still the single source of truth at build time; drift is only possible at a deliberate re-pin.bundle:corebuild step (esbuild) compiles the dep'sdist/coreintodist/vendor/dspack-gen-core.js(26.6kb, ESM;ajvexternal since ds-mcp already depends on it directly).filesalready shipsdist/.get-generation-context/validate-uiimport the bundle via a relative specifier;src/vendor/dspack-gen-core.d.tsre-exports the real dspack-gen types so tsc type-checks against the pinned dep.dist/vendor(the artifact that actually ships).Verification
scripts/smoke.shgreen (11 tools).npm pack→ install tarball in an empty dir → no dspack-gen in node_modules; againstexamples/shadcn-ui-v04.dspack.json,tools/listreturns 11 tools,get-generation-context {intent: "destructive-action"}returns the full compiled context (190KB),validate-uireturns a passing S1/S2/S3 gate report.Unblocks publishing 0.3.0 to npm (separate step after merge).
🤖 Generated with Claude Code