- Complete the bundler external lists against the AGENTS.md invariant rather than against today's reachability: chokidar, hono and react to clients/cli, chokidar and hono to clients/tui, react to the web runner. Every root-declared package core/ imports at runtime is now named in all three, so a new import in core/ cannot silently inline one. - AGENTS.md: split the single over-broad bullet in two. commander, open, @hono/node-server, vite and @vitejs/plugin-react are root dependencies reached only from client code, so they are not part of the core/ set and need naming only in the external list of the client that imports them. Give the vitest.shared.mts pins their own rule, stating the react/react-dom exception instead of implying every root-owned package is aliased to the root. - vitest.shared.mts: the umbrella comment now says root-OWNED rather than root runtime dependency — express is test-only and lives in the root devDependencies — and notes that the list is deliberately not the complete root set, since a package that resolves unambiguously needs no pin. - local-dev skill: document why react/react-dom stay client-pinned, which the previous text contradicted. npm run local:gate and npm run verify:bundle-externals pass. Signed-off-by: cliffhall <cliff@futurescale.com>
72 lines
3.1 KiB
TypeScript
72 lines
3.1 KiB
TypeScript
import { defineConfig } from "tsup";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = path.resolve(dirname, "../..");
|
|
|
|
export default defineConfig({
|
|
entry: {
|
|
index: "src/index.ts",
|
|
},
|
|
format: ["esm"],
|
|
outDir: "build",
|
|
clean: true,
|
|
// No source maps in the published bundle — they roughly double the on-disk
|
|
// size and aren't needed at runtime (debug via `npm run dev` on the source).
|
|
sourcemap: false,
|
|
target: "node22",
|
|
platform: "node",
|
|
// Bundle core source; leave npm deps external.
|
|
noExternal: [/^@inspector\/core/],
|
|
external: [
|
|
// `undici` MUST stay external. It is CommonJS, so inlining it rewrites
|
|
// `import("undici")` to a relative chunk whose `require("assert")` hits
|
|
// esbuild's ESM `__require` shim and throws "Dynamic require of \"assert\"
|
|
// is not supported" — and because the specifier was rewritten at build time,
|
|
// no user-side install can ever satisfy it (#2067). It is declared in the
|
|
// ROOT manifest only, so tsup cannot infer this from a nearest-manifest
|
|
// lookup; the entry has to be explicit.
|
|
"undici",
|
|
"@napi-rs/keyring",
|
|
// Root-declared (see the repo's dependency-placement rule) and CJS, which
|
|
// is the combination that bites: tsup externalizes what the *client's*
|
|
// package.json declares, so a root-only dependency is bundled unless named
|
|
// here — and inlining a CJS module into an ESM bundle leaves esbuild's
|
|
// `Dynamic require of "path" is not supported` shim, which throws at
|
|
// import time and takes the whole binary down before it parses a flag.
|
|
"proper-lockfile",
|
|
"@modelcontextprotocol/client",
|
|
"@modelcontextprotocol/core",
|
|
// Root-declared and reached through `core/mcp/apps.ts`, so it must be
|
|
// external here like every other root runtime dependency (AGENTS.md). This
|
|
// client was actually inlining it — dragging the transitive v1 SDK and
|
|
// zod-to-json-schema in with it — which the #2067 guard surfaced. ESM, so it
|
|
// was not failing the way `undici` did; the rule is what it violated.
|
|
"@modelcontextprotocol/ext-apps",
|
|
"commander",
|
|
"pino",
|
|
// Consolidated to the ROOT manifest by #2195, along with every other
|
|
// runtime dependency `core/` imports. tsup externalizes only what the
|
|
// *nearest* package.json declares, so once a client stops declaring one it
|
|
// must be named here or esbuild inlines it — the #2067 failure class, now
|
|
// reached by a manifest edit rather than an omission.
|
|
"ajv",
|
|
"atomically",
|
|
"open",
|
|
"zod",
|
|
// Reached through `core/` but not through this client's own code today.
|
|
// AGENTS.md requires every root-declared package `core/` imports at runtime
|
|
// in ALL three lists regardless, because which client reaches one is a
|
|
// function of what `core/` imports rather than of what the client names —
|
|
// so the list must not depend on today's reachability (Copilot).
|
|
"chokidar",
|
|
"hono",
|
|
"react",
|
|
],
|
|
esbuildOptions(options) {
|
|
options.alias = {
|
|
"@inspector/core": path.join(repoRoot, "core"),
|
|
};
|
|
},
|
|
});
|