chore: make bundle fully self-contained, no external imports

- Remove uncagedWorkflowExternals() from scaffold build script
- Remove --external from Bun.build config
- Tighten bundle validator: only Node built-ins allowed, all deps must be inlined
- Update skill.ts documentation

Bundles are now deterministic — same Node/Bun version = same behavior,
no dependency resolution at runtime.
This commit is contained in:
2026-05-16 05:12:49 +00:00
parent 4ea1e0d8a4
commit c1a17b707c
3 changed files with 4 additions and 45 deletions
@@ -196,18 +196,13 @@ uncaged-workflow init workspace ${workspaceName}
function bundleTs(): string {
return [
'import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";',
'import { mkdir, readdir, writeFile } from "node:fs/promises";',
'import { join } from "node:path";',
"",
'const rootDir = join(import.meta.dir, "..");',
'const workflowsDir = join(rootDir, "workflows");',
'const distDir = join(rootDir, "dist");',
"",
"type JsonDeps = {",
" dependencies: Record<string, string> | null;",
" devDependencies: Record<string, string> | null;",
"};",
"",
"function isEntryFile(name: string): boolean {",
' return name.endsWith("-entry.ts");',
"}",
@@ -216,36 +211,6 @@ function bundleTs(): string {
' return name.slice(0, -".ts".length);',
"}",
"",
"async function uncagedWorkflowExternals(): Promise<string[]> {",
" const names = new Set<string>();",
' const paths = [join(rootDir, "package.json"), join(workflowsDir, "package.json")];',
" for (const pkgPath of paths) {",
" let raw: string;",
" try {",
' raw = await readFile(pkgPath, "utf8");',
" } catch {",
" continue;",
" }",
" const parsed = JSON.parse(raw) as JsonDeps;",
" const blocks = [parsed.dependencies, parsed.devDependencies];",
" for (const block of blocks) {",
" if (block == null) {",
" continue;",
" }",
" for (const key of Object.keys(block)) {",
' if (key.startsWith("@uncaged/workflow")) {',
" names.add(key);",
" }",
" }",
" }",
" }",
" if (names.size === 0) {",
' names.add("@uncaged/workflow-runtime");',
' names.add("@uncaged/workflow-protocol");',
" }",
" return [...names];",
"}",
"",
"async function main(): Promise<void> {",
" await mkdir(distDir, { recursive: true });",
" let files: string[];",
@@ -261,7 +226,6 @@ function bundleTs(): string {
' console.warn("bundle: no *-entry.ts files under workflows/");',
" return;",
" }",
" const external = await uncagedWorkflowExternals();",
" for (const file of entries) {",
" const stem = entryStem(file);",
" const entryPath = join(workflowsDir, file);",
@@ -272,7 +236,6 @@ function bundleTs(): string {
' target: "node",',
" splitting: false,",
' naming: { entry: "[name].esm.js" },',
" external,",
" });",
" if (!result.success) {",
" for (const log of result.logs) {",
+1 -2
View File
@@ -329,9 +329,8 @@ const adapter = createCursorAgent({
The bundle validator only allows these import specifiers:
- Node built-ins (\`node:fs\`, \`node:path\`, etc.)
- \`@uncaged/workflow-*\` packages
Third-party packages (**including zod**) must be bundled into the \`.esm.js\` file, not left as external imports. When using \`bun build\`, only mark \`@uncaged/*\` as external.
All other dependencies — including \`@uncaged/workflow-*\` packages, zod, and any third-party code — must be bundled into the \`.esm.js\` file. Bundles are fully self-contained: same Node/Bun version = same behavior.
### No default exports
@@ -37,9 +37,6 @@ function isAllowedImportSpecifier(spec: string): boolean {
if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("file:")) {
return false;
}
if (spec.startsWith("@uncaged/workflow")) {
return true;
}
return isBuiltin(spec);
}
@@ -294,7 +291,7 @@ function validateImportDeclaration(node: ImportDeclaration): string | null {
return "only static string import specifiers are allowed";
}
if (!isAllowedImportSpecifier(spec)) {
return `disallowed import specifier "${spec}" (only Node built-ins and @uncaged/workflow-* packages are allowed)`;
return `disallowed import specifier "${spec}" (only Node built-ins are allowed; all other dependencies must be bundled)`;
}
return null;
}
@@ -309,7 +306,7 @@ function validateExportSource(
return staticMessage;
}
if (!isAllowedImportSpecifier(spec)) {
return `${disallowedPrefix} "${spec}" (only Node built-ins and @uncaged/workflow-* packages are allowed)`;
return `${disallowedPrefix} "${spec}" (only Node built-ins are allowed; all other dependencies must be bundled)`;
}
return null;
}