From 4d346efda719059880c913d9c3c1a0e12af6db73 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Sat, 5 Sep 2026 00:45:10 +0000 Subject: [PATCH] docs: state the self-contained plugin output rule (no autoExternal, no externals) --- AGENTS.md | 30 +++++++++++++++++++ docs/entry-conventions.md | 6 +++- .../docs/en/guide/distribution/validation.mdx | 16 ++++++++++ .../docs/zh/guide/distribution/validation.mdx | 11 +++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index df277720d..68eb083ab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,6 +62,36 @@ - Never accept or capture a Workbench route while its loading state is still visible. - Browser acceptance must cover populated state plus the documented stale-diagnostic and repair flow. +## Generated plugin output + +- Generated plugin output is self-contained. The compiler profile in + `packages/agent-bundle/src/build/rslib.ts` (`composeEntryLibConfig`) bundles + every dependency of a generated executable — `autoExternal: false`, + `bundle: true`, `splitChunks: false`, no `externals`. Rslib's `node` target + leaves only Node built-ins (and `pnpapi`) external, and the only bare + specifiers `AB6005` accepts in a host-pack module are Node built-ins, so a + generated executable in a host pack loads nothing else from outside the + artifact. MCP App views + (`src/build/mcp-apps.ts`) inline every script and style into one HTML file. + The framework never adds `externals` to a plugin build; the `externals` + handling in `rslib.ts` (`reservedExternalsViolation`, + `guardReservedExternals`) only rejects reserved specifiers in the resolved + externals, which come from the author's `tools` hatch and Rslib's built-in + list, never from the profile. +- No refactor, toolchain upgrade, or "leaner install" change may enable + `autoExternal` or externalize a dependency on the author's behalf. A package + a consumer must install is the author's explicit decision — an import kept + external through the `tools` hatch, a packed declaration reference, an + install script — and the prepack gate judges it: `AB7014` demands + packed-file evidence of use, `AB7015` a specifier a consumer's npm can + install. +- Proof is bytes and processes, not config: every artifact build walks the + compiled host-pack modules (`AB6005` fails a bare package specifier there; + the package build's `dist` is judged by the prepack gate instead), and the + packed pool (`pnpm test:packed`) installs the packed tarball into a clean + consumer, builds, removes the project source, and spawns the generated + entry as a real process (`packed-deleted-source`). + ## Documentation site - `website/` is the public Rspress docsite diff --git a/docs/entry-conventions.md b/docs/entry-conventions.md index d68a201c3..5a3050b63 100644 --- a/docs/entry-conventions.md +++ b/docs/entry-conventions.md @@ -1207,7 +1207,11 @@ module specifier (`agent-bundle/meta`, or a registry specifier such as `agent-bundle/mcp-apps`) fails the build with a hard diagnostic — at config inspection for statically visible `externals`, and through a post-build scan of the emitted bundle for function-form `externals` — because generated executables must stay self-contained. The -hatch customizes *how code compiles*, never *what the artifact promises*. +hatch customizes *how code compiles*, never *what the artifact promises*. The +framework's own profile keeps the same promise: `autoExternal` is off, +`bundle: true`, `splitChunks: false`, and no `externals` are added, so Rslib's +`node` target leaves only Node built-ins (and `pnpapi`) external, and `AB6005` +fails any bare specifier that is not a Node built-in in a host-pack module. The hatch merges *beside* the framework profile, not over it: `plugins` arrays concatenate, and Rsbuild's plugin manager appends every plugin it is diff --git a/website/docs/en/guide/distribution/validation.mdx b/website/docs/en/guide/distribution/validation.mdx index e7e71f095..e58e9293e 100644 --- a/website/docs/en/guide/distribution/validation.mdx +++ b/website/docs/en/guide/distribution/validation.mdx @@ -186,6 +186,22 @@ through the `tools` escape hatch — which belongs under `dependencies`, and `AB `output.distPath`, defaulting to `artifact`. Use it as an npm `prepack` script; `--ignore-scripts` prevents recursion, and no npm lifecycle ever performs a host install. +That inlining is the compiler's contract, not a bundler default a toolchain upgrade may flip. +Generated executables — artifact scripts, the routed CLI, MCP entries, hook wrappers, and the +package build's JavaScript bundles — compile with Rslib's `autoExternal` disabled, `bundle: true`, +and `splitChunks: false`, and the framework adds no `externals` of its own; Rslib's `node` target +leaves only Node built-ins (`node:fs`, `path`, plus Yarn PnP's `pnpapi`) external. MCP App views +inline every script and style into one HTML file. Artifact validation holds the compiled host-pack +bytes to the same line: a bare specifier that is not a Node built-in is `AB6005`, so a generated +executable in a host pack loads nothing but built-ins from outside the artifact. A `dependencies` +entry is therefore only for what the packed files demonstrably need from outside a compiled bundle +— a package a packed module still imports because the author kept it external through the +[`tools` hatch](../../reference/configuration.mdx#tools) (possible in the package build's `dist` +output, which `AB6005` does not walk; a host-pack module with that import fails the build), one a +consumer-side install script runs, one whose `bin` a packed file executes, or one a packed +declaration file references — and `AB7014` reports a declared dependency with none of that +evidence, while `AB7015` reports one a consumer's npm cannot install. + | Code | Meaning | | --- | --- | | `AB7010` | The dry-run npm inventory omits a package output, artifact manifest or file, install surface, or README. Include `dist` and the artifact directory in the package `files` allowlist. | diff --git a/website/docs/zh/guide/distribution/validation.mdx b/website/docs/zh/guide/distribution/validation.mdx index 1294b31b1..80b53463a 100644 --- a/website/docs/zh/guide/distribution/validation.mdx +++ b/website/docs/zh/guide/distribution/validation.mdx @@ -165,6 +165,17 @@ npx agent-bundle prepack --root . --output artifact --json `output.distPath`,默认值为 `artifact`。把它用作 npm 的 `prepack` 脚本;`--ignore-scripts` 可防止递归, 而且任何 npm 生命周期都绝不会执行宿主安装。 +这种内联是编译器的契约,而不是一次工具链升级就可能翻转的打包器默认值。生成的可执行文件——产物脚本、路由式 +CLI、MCP 入口、钩子包装层以及包构建的 JavaScript bundle——都以禁用 Rslib 的 `autoExternal`、`bundle: true` 与 +`splitChunks: false` 的配置编译,框架自身也不添加任何 `externals`;Rslib 的 `node` target 只把 Node 内建模块(`node:fs`、`path`, +以及 Yarn PnP 的 `pnpapi`)保持外部化。MCP App 视图则把每个脚本与样式都内联进同一个 HTML 文件。产物校验对 +编译出的宿主包字节坚持同一条界线:任何不是 Node 内建模块的裸说明符即为 `AB6005`,因此宿主包中生成的可执行文件 +从产物之外加载的只有内建模块。因此,`dependencies` 条目只留给打包后的文件有据可证地需要从已编译 bundle 之外 +获取的内容——打包后的模块因作者通过 [`tools` 逃生舱](../../reference/configuration.mdx#tools)将其保持外部化 +而仍然导入的包(这在包构建的 `dist` 输出中是可能的,因为 `AB6005` 不会遍历它;带有这种导入的宿主包模块则会 +让构建失败),消费者侧安装脚本运行的包,打包后的文件执行其 `bin` 的包,或打包后的声明文件引用的包—— +`AB7014` 会报告不具备上述任何一种证据的已声明依赖,而 `AB7015` 会报告消费者的 npm 无法安装的依赖。 + | 代码 | 含义 | | --- | --- | | `AB7010` | dry-run 的 npm 清单遗漏了某个包输出、产物清单或文件、安装表面,或 README。请把 `dist` 与产物目录加入包的 `files` 允许列表。 |