From c1a17b707cd913343f2d00d7308062f559af7217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Sat, 16 May 2026 05:12:49 +0000 Subject: [PATCH] chore: make bundle fully self-contained, no external imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- .../src/commands/init/workspace.ts | 39 +------------------ packages/cli-workflow/src/skill.ts | 3 +- .../src/bundle/bundle-validator.ts | 7 +--- 3 files changed, 4 insertions(+), 45 deletions(-) diff --git a/packages/cli-workflow/src/commands/init/workspace.ts b/packages/cli-workflow/src/commands/init/workspace.ts index 580d26d..317eb6e 100644 --- a/packages/cli-workflow/src/commands/init/workspace.ts +++ b/packages/cli-workflow/src/commands/init/workspace.ts @@ -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 | null;", - " devDependencies: Record | 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 {", - " const names = new Set();", - ' 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 {", " 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) {", diff --git a/packages/cli-workflow/src/skill.ts b/packages/cli-workflow/src/skill.ts index 6b82c5c..30dc9ca 100644 --- a/packages/cli-workflow/src/skill.ts +++ b/packages/cli-workflow/src/skill.ts @@ -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 diff --git a/packages/workflow-register/src/bundle/bundle-validator.ts b/packages/workflow-register/src/bundle/bundle-validator.ts index 8d26bee..c021dc6 100644 --- a/packages/workflow-register/src/bundle/bundle-validator.ts +++ b/packages/workflow-register/src/bundle/bundle-validator.ts @@ -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; }